Merge "profiling: Add matcher."
diff --git a/src/perfetto_cmd/config.cc b/src/perfetto_cmd/config.cc
index 106d3ff..d786818 100644
--- a/src/perfetto_cmd/config.cc
+++ b/src/perfetto_cmd/config.cc
@@ -86,16 +86,22 @@
bool CreateConfigFromOptions(const ConfigOptions& options,
TraceConfig* config) {
uint64_t duration_ms = 0;
- if (!ConvertTimeToMs(options.time, &duration_ms))
+ if (!ConvertTimeToMs(options.time, &duration_ms)) {
+ PERFETTO_ELOG("--time argument is invalid");
return false;
+ }
uint64_t buffer_size_kb = 0;
- if (!ConvertSizeToKb(options.buffer_size, &buffer_size_kb))
+ if (!ConvertSizeToKb(options.buffer_size, &buffer_size_kb)) {
+ PERFETTO_ELOG("--buffer argument is invalid");
return false;
+ }
uint64_t max_file_size_kb = 0;
- if (!ConvertSizeToKb(options.max_file_size, &max_file_size_kb))
+ if (!ConvertSizeToKb(options.max_file_size, &max_file_size_kb)) {
+ PERFETTO_ELOG("--size argument is invalid");
return false;
+ }
std::vector<std::string> ftrace_events;
std::vector<std::string> atrace_categories;
@@ -110,7 +116,7 @@
}
config->set_duration_ms(static_cast<unsigned int>(duration_ms));
- config->set_max_file_size_bytes(static_cast<unsigned int>(max_file_size_kb));
+ config->set_max_file_size_bytes(max_file_size_kb * 1024);
if (max_file_size_kb)
config->set_write_into_file(true);
config->add_buffers()->set_size_kb(static_cast<unsigned int>(buffer_size_kb));
diff --git a/src/perfetto_cmd/config.h b/src/perfetto_cmd/config.h
index 6d4b48c..65bad22 100644
--- a/src/perfetto_cmd/config.h
+++ b/src/perfetto_cmd/config.h
@@ -29,7 +29,7 @@
// options in a proto is the job of CreateConfigFromOptions.
struct ConfigOptions {
- std::string time;
+ std::string time = "10s";
std::string max_file_size;
std::string buffer_size = "32mb";
std::vector<std::string> atrace_apps;
diff --git a/src/perfetto_cmd/config_unittest.cc b/src/perfetto_cmd/config_unittest.cc
index 527e9da..3b90cc8 100644
--- a/src/perfetto_cmd/config_unittest.cc
+++ b/src/perfetto_cmd/config_unittest.cc
@@ -105,6 +105,16 @@
ASSERT_TRUE(CreateConfigFromOptions(options, &config));
}
+TEST_F(CreateConfigFromOptionsTest, InvalidTime) {
+ options.time = "2mb";
+ ASSERT_FALSE(CreateConfigFromOptions(options, &config));
+}
+
+TEST_F(CreateConfigFromOptionsTest, InvalidSize) {
+ options.max_file_size = "2s";
+ ASSERT_FALSE(CreateConfigFromOptions(options, &config));
+}
+
TEST_F(CreateConfigFromOptionsTest, FullConfig) {
options.buffer_size = "100mb";
options.max_file_size = "1gb";
@@ -114,7 +124,7 @@
options.atrace_apps.push_back("com.android.chrome");
ASSERT_TRUE(CreateConfigFromOptions(options, &config));
EXPECT_EQ(config.duration_ms(), 60 * 60 * 1000);
- EXPECT_EQ(config.max_file_size_bytes(), 1 * 1024 * 1024);
+ EXPECT_EQ(config.max_file_size_bytes(), 1 * 1024 * 1024 * 1024);
EXPECT_EQ(config.buffers().Get(0).size_kb(), 100 * 1024);
EXPECT_EQ(config.data_sources().Get(0).config().name(), "linux.ftrace");
EXPECT_EQ(config.data_sources().Get(0).config().target_buffer(), 0);
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 48a3740..d0b59a9 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -146,7 +146,7 @@
light configuration flags: (only when NOT using -c/--config)
--time -t : Trace duration N[s,m,h] (default: 10s)
--buffer -b : Ring buffer size N[mb,gb] (default: 32mb)
- --size -s : Maximum trace size N[mb,gb] (default: 100mb)
+ --size -s : Max file size N[mb,gb] (default: in-memory ring-buffer only)
ATRACE_CAT : Record ATRACE_CAT (e.g. wm)
FTRACE_GROUP/FTRACE_NAME : Record ftrace event (e.g. sched/sched_switch)
FTRACE_GROUP/* : Record all events in group (e.g. sched/*)
@@ -353,11 +353,11 @@
} else {
parsed = trace_config_proto.ParseFromString(trace_config_raw);
}
+ }
- if (!parsed) {
- PERFETTO_ELOG("Could not parse TraceConfig proto");
- return 1;
- }
+ if (!parsed) {
+ PERFETTO_ELOG("The trace config is invalid, bailing out.");
+ return 1;
}
*trace_config_proto.mutable_statsd_metadata() = std::move(statsd_metadata);
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 51b4579..f4810db 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -347,6 +347,13 @@
}
if (sql_query.back() == '\n')
sql_query.resize(sql_query.size() - 1);
+
+ // If we have a new line at the end of the file or an extra new line
+ // somewhere in the file, we'll end up with an empty query which we should
+ // just ignore.
+ if (sql_query.empty())
+ continue;
+
PERFETTO_ILOG("Executing query: %s", sql_query.c_str());
protos::RawQueryArgs query;
diff --git a/tools/heap_profile b/tools/heap_profile
index ef49ffe..d37f325 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -91,7 +91,7 @@
'''
PERFETTO_CMD=('CFG=\'{}\'; echo ${{CFG}} | '
- 'perfetto -t -c - -o /data/misc/perfetto-traces/profile -b')
+ 'perfetto --txt -c - -o /data/misc/perfetto-traces/profile -d')
IS_INTERRUPTED = False
def sigint_handler(sig, frame):
global IS_INTERRUPTED
diff --git a/tools/tmux b/tools/tmux
index e3d7a82..18e387f 100755
--- a/tools/tmux
+++ b/tools/tmux
@@ -120,9 +120,6 @@
if ! is_monolithic $OUT; then
PREFIX="$PREFIX LD_LIBRARY_PATH=$DIR"
push $OUT/libperfetto.so
- if is_android $OUT; then
- push $OUT/libperfetto_android_internal.so
- fi
fi
CONFIG_DEVICE_PATH=$CONFIG
diff --git a/ui/src/common/protos.ts b/ui/src/common/protos.ts
index 3db7694..3ada5fd 100644
--- a/ui/src/common/protos.ts
+++ b/ui/src/common/protos.ts
@@ -16,10 +16,13 @@
// Aliases protos to avoid the super nested namespaces.
// See https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases
+import IAndroidPowerConfig = protos.perfetto.protos.IAndroidPowerConfig;
import IProcessStatsConfig = protos.perfetto.protos.IProcessStatsConfig;
import IRawQueryArgs = protos.perfetto.protos.IRawQueryArgs;
import ISysStatsConfig = protos.perfetto.protos.ISysStatsConfig;
import ITraceConfig = protos.perfetto.protos.ITraceConfig;
+import BatteryCounters =
+ protos.perfetto.protos.AndroidPowerConfig.BatteryCounters;
import MeminfoCounters = protos.perfetto.protos.MeminfoCounters;
import RawQueryArgs = protos.perfetto.protos.RawQueryArgs;
import RawQueryResult = protos.perfetto.protos.RawQueryResult;
@@ -84,10 +87,12 @@
}
export {
+ IAndroidPowerConfig,
IProcessStatsConfig,
IRawQueryArgs,
ISysStatsConfig,
ITraceConfig,
+ BatteryCounters,
MeminfoCounters,
RawQueryArgs,
RawQueryResult,
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 564104e..36d6b3b 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -95,6 +95,11 @@
vmstatCounters: string[];
statPeriodMs: number|null;
statCounters: string[];
+
+ // Battery and power
+ power: boolean;
+ batteryPeriodMs: number|null;
+ batteryCounters: string[];
}
export interface TraceTime {
@@ -185,5 +190,9 @@
vmstatCounters: [],
statPeriodMs: null,
statCounters: [],
+
+ power: false,
+ batteryPeriodMs: 1000,
+ batteryCounters: [],
};
}
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index 8901585..6d0ae99 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -14,6 +14,8 @@
import {TraceConfig} from '../common/protos';
import {
+ BatteryCounters,
+ IAndroidPowerConfig,
IProcessStatsConfig,
ISysStatsConfig,
ITraceConfig,
@@ -106,6 +108,22 @@
});
}
+ if (config.power) {
+ const androidPowerConfig: IAndroidPowerConfig = {};
+ androidPowerConfig.batteryPollMs = config.batteryPeriodMs;
+ androidPowerConfig.batteryCounters = config.batteryCounters.map(name => {
+ // tslint:disable-next-line no-any
+ return BatteryCounters[name as any as number] as any as number;
+ });
+
+ dataSources.push({
+ config: {
+ name: 'android.power',
+ androidPowerConfig,
+ },
+ });
+ }
+
const proto: ITraceConfig = {
durationMs,
buffers: [
@@ -137,7 +155,7 @@
// fields are enums.
function looksLikeEnum(value: string): boolean {
return value.startsWith('MEMINFO_') || value.startsWith('VMSTAT_') ||
- value.startsWith('STAT_');
+ value.startsWith('STAT_') || value.startsWith('BATTERY_COUNTER_');
}
function* message(msg: {}, indent: number): IterableIterator<string> {
for (const [key, value] of Object.entries(msg)) {
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index fe60595..6abc4bc 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -382,6 +382,10 @@
vmstatCounters: [],
statPeriodMs: null,
statCounters: [],
+
+ power: true,
+ batteryPeriodMs: 1000,
+ batteryCounters: ['BATTERY_COUNTER_CHARGE', 'BATTERY_COUNTER_CURRENT'],
},
},
{
@@ -421,6 +425,10 @@
vmstatCounters: [],
statPeriodMs: null,
statCounters: [],
+
+ power: false,
+ batteryPeriodMs: null,
+ batteryCounters: [],
},
},
{
@@ -449,6 +457,10 @@
vmstatCounters: [],
statPeriodMs: null,
statCounters: [],
+
+ power: false,
+ batteryPeriodMs: null,
+ batteryCounters: [],
},
},
];
@@ -465,11 +477,21 @@
];
ATRACE_CATERGORIES.sort();
+
+const BATTERY_COUNTERS = [
+ 'BATTERY_COUNTER_CHARGE',
+ 'BATTERY_COUNTER_CAPACITY_PERCENT',
+ 'BATTERY_COUNTER_CURRENT',
+ 'BATTERY_COUNTER_CURRENT_AVG'
+];
+BATTERY_COUNTERS.sort();
+
const DURATION_HELP = `Duration to trace for`;
const BUFFER_SIZE_HELP = `Size of the ring buffer which stores the trace`;
const PROCESS_METADATA_HELP =
`Record process names and parent child relationships`;
const FTRACE_AND_ATRACE_HELP = `Record ftrace & atrace events`;
+const POWER_HELP = `Poll battery counters from the Power Management Unit`;
const SYS_STATS_HELP = ``;
function toId(label: string): string {
@@ -929,6 +951,39 @@
),
+ m('.heading', m(Toggle, {
+ label: 'Battery and power',
+ help: POWER_HELP,
+ value: config.power,
+ enabled: true,
+ onchange: onChange<boolean|null>('power'),
+ })),
+
+ m('.control-group',
+ m(Numeric, {
+ enabled: config.power,
+ label: 'Polling rate',
+ sublabel: 'ms',
+ help: '',
+ placeholder: 'never',
+ value: config.batteryPeriodMs,
+ onchange: onChange<number|null>('batteryPeriodMs'),
+ presets: [
+ {label: '1000ms', value: 1000},
+ {label: '5000ms', value: 5000},
+ {label: '10000ms', value: 10000},
+ ]
+ }),
+ m(MultiSelect, {
+ label: 'Battery counters',
+ enabled: config.power && isTruthy(config.batteryPeriodMs),
+ selected: config.batteryCounters,
+ options: BATTERY_COUNTERS,
+ onadd: onAdd('batteryCounters'),
+ onsubtract: onSubtract('batteryCounters'),
+ }),
+ ),
+
m('hr'),
m(Toggle, {