Merge "Sticky header tracks"
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 6c8106c..2995192 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -1013,7 +1013,6 @@
"android-unwinding/libunwindstack/ElfInterfaceArm.cpp",
"android-unwinding/libunwindstack/Global.cpp",
"android-unwinding/libunwindstack/JitDebug.cpp",
- "android-unwinding/libunwindstack/LocalUnwinder.cpp",
"android-unwinding/libunwindstack/MapInfo.cpp",
"android-unwinding/libunwindstack/Maps.cpp",
"android-unwinding/libunwindstack/Memory.cpp",
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index fb26bbc..63b058f 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -9097,6 +9097,9 @@
UNWIND_ERROR_SYSTEM_CALL = 9;
UNWIND_ERROR_THREAD_TIMEOUT = 10;
UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11;
+ UNWIND_ERROR_BAD_ARCH = 12;
+ UNWIND_ERROR_MAPS_PARSE = 13;
+ UNWIND_ERROR_INVALID_PARAMETER = 14;
}
}
diff --git a/protos/perfetto/trace/profiling/profile_packet.proto b/protos/perfetto/trace/profiling/profile_packet.proto
index f599f17..d58e6e7 100644
--- a/protos/perfetto/trace/profiling/profile_packet.proto
+++ b/protos/perfetto/trace/profiling/profile_packet.proto
@@ -271,6 +271,9 @@
UNWIND_ERROR_SYSTEM_CALL = 9;
UNWIND_ERROR_THREAD_TIMEOUT = 10;
UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11;
+ UNWIND_ERROR_BAD_ARCH = 12;
+ UNWIND_ERROR_MAPS_PARSE = 13;
+ UNWIND_ERROR_INVALID_PARAMETER = 14;
}
}
diff --git a/src/profiling/common/unwind_support.cc b/src/profiling/common/unwind_support.cc
index 48ff5cf..a070ee2 100644
--- a/src/profiling/common/unwind_support.cc
+++ b/src/profiling/common/unwind_support.cc
@@ -161,6 +161,12 @@
return "THREAD_DOES_NOT_EXIST";
case unwindstack::ERROR_THREAD_TIMEOUT:
return "THREAD_TIMEOUT";
+ case unwindstack::ERROR_BAD_ARCH:
+ return "BAD_ARCH";
+ case unwindstack::ERROR_MAPS_PARSE:
+ return "MAPS_PARSE";
+ case unwindstack::ERROR_INVALID_PARAMETER:
+ return "INVALID_PARAMETER";
}
}
diff --git a/src/profiling/perf/event_reader.cc b/src/profiling/perf/event_reader.cc
index de05f8b..3c6271a 100644
--- a/src/profiling/perf/event_reader.cc
+++ b/src/profiling/perf/event_reader.cc
@@ -135,7 +135,9 @@
ret.metadata_page_ = reinterpret_cast<perf_event_mmap_page*>(mmap_addr);
ret.data_buf_ = reinterpret_cast<char*>(mmap_addr) + base::kPageSize;
PERFETTO_CHECK(ret.metadata_page_->data_offset == base::kPageSize);
- PERFETTO_CHECK(ret.metadata_page_->data_size = ret.data_buf_sz_);
+ PERFETTO_CHECK(ret.metadata_page_->data_size == ret.data_buf_sz_);
+
+ PERFETTO_DCHECK(IsPowerOfTwo(ret.data_buf_sz_));
return base::make_optional(std::move(ret));
}
@@ -178,8 +180,6 @@
// event wrapped - reconstruct it, and return a pointer to the buffer
if (read_pos + evt_size > data_buf_sz_) {
- PERFETTO_DCHECK(read_pos + evt_size !=
- ((read_pos + evt_size) & (data_buf_sz_ - 1)));
PERFETTO_DLOG("PerfRingBuffer: returning reconstructed event");
size_t prefix_sz = data_buf_sz_ - read_pos;
@@ -189,9 +189,6 @@
return &reconstructed_record_[0];
} else {
// usual case - contiguous sample
- PERFETTO_DCHECK(read_pos + evt_size ==
- ((read_pos + evt_size) & (data_buf_sz_ - 1)));
-
return data_buf_ + read_pos;
}
}
diff --git a/src/profiling/perf/perf_producer.cc b/src/profiling/perf/perf_producer.cc
index 22c4a6d..8582885 100644
--- a/src/profiling/perf/perf_producer.cc
+++ b/src/profiling/perf/perf_producer.cc
@@ -284,6 +284,12 @@
return Profiling::UNWIND_ERROR_THREAD_TIMEOUT;
case unwindstack::ERROR_THREAD_DOES_NOT_EXIST:
return Profiling::UNWIND_ERROR_THREAD_DOES_NOT_EXIST;
+ case unwindstack::ERROR_BAD_ARCH:
+ return Profiling::UNWIND_ERROR_BAD_ARCH;
+ case unwindstack::ERROR_MAPS_PARSE:
+ return Profiling::UNWIND_ERROR_MAPS_PARSE;
+ case unwindstack::ERROR_INVALID_PARAMETER:
+ return Profiling::UNWIND_ERROR_INVALID_PARAMETER;
}
return Profiling::UNWIND_ERROR_UNKNOWN;
}
diff --git a/src/trace_processor/importers/proto/profile_packet_utils.h b/src/trace_processor/importers/proto/profile_packet_utils.h
index 2dde388..08c8a46 100644
--- a/src/trace_processor/importers/proto/profile_packet_utils.h
+++ b/src/trace_processor/importers/proto/profile_packet_utils.h
@@ -113,6 +113,12 @@
return "thread_timeout";
case Profiling::UNWIND_ERROR_THREAD_DOES_NOT_EXIST:
return "thread_does_not_exist";
+ case Profiling::UNWIND_ERROR_BAD_ARCH:
+ return "bad_arch";
+ case Profiling::UNWIND_ERROR_MAPS_PARSE:
+ return "maps_parse";
+ case Profiling::UNWIND_ERROR_INVALID_PARAMETER:
+ return "invalid_parameter";
}
return "unknown"; // switch should be complete, but gcc needs a hint
}
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index e6dd7c6..4d202e5 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -234,7 +234,7 @@
PERFETTO_ELOG(
"It is strongly recommended to have flush_period_ms set when "
"write_into_file is turned on. This trace will be loaded fully "
- "into memory before sorting which increases the likliehoold of "
+ "into memory before sorting which increases the likelihood of "
"OOMs.");
}
}
diff --git a/src/trace_processor/importers/systrace/systrace_parser.cc b/src/trace_processor/importers/systrace/systrace_parser.cc
index 7e9accd..a8c5854 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser.cc
@@ -217,7 +217,9 @@
break;
}
- case 'N': {
+ case 'N':
+ case 'T':
+ case 'U': {
StringId name_id = context_->storage->InternString(point.name);
StringId track_name_id = context_->storage->InternString(point.str_value);
UniquePid upid =
@@ -225,9 +227,21 @@
auto track_set_id =
context_->async_track_set_tracker->InternProcessTrackSet(
upid, track_name_id);
- TrackId track_id =
- context_->async_track_set_tracker->Scoped(track_set_id, ts, 0);
- context_->slice_tracker->Scoped(ts, track_id, kNullStringId, name_id, 0);
+
+ if (point.phase == 'N') {
+ TrackId track_id =
+ context_->async_track_set_tracker->Scoped(track_set_id, ts, 0);
+ context_->slice_tracker->Scoped(ts, track_id, kNullStringId, name_id,
+ 0);
+ } else if (point.phase == 'T') {
+ TrackId track_id = context_->async_track_set_tracker->Begin(
+ track_set_id, point.int_value);
+ context_->slice_tracker->Begin(ts, track_id, kNullStringId, name_id);
+ } else if (point.phase == 'U') {
+ TrackId track_id = context_->async_track_set_tracker->End(
+ track_set_id, point.int_value);
+ context_->slice_tracker->End(ts, track_id);
+ }
break;
}
diff --git a/src/trace_processor/importers/systrace/systrace_parser.h b/src/trace_processor/importers/systrace/systrace_parser.h
index c6e506a..af0f21f 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_parser.h
@@ -75,6 +75,22 @@
std::move(track_name));
}
+ static SystraceTracePoint T(uint32_t tgid,
+ base::StringView track_name,
+ base::StringView name,
+ int64_t cookie) {
+ return SystraceTracePoint('T', tgid, std::move(name), cookie,
+ std::move(track_name));
+ }
+
+ static SystraceTracePoint U(uint32_t tgid,
+ base::StringView track_name,
+ base::StringView name,
+ int64_t cookie) {
+ return SystraceTracePoint('U', tgid, std::move(name), cookie,
+ std::move(track_name));
+ }
+
SystraceTracePoint(char p,
uint32_t tg,
base::StringView n,
@@ -82,18 +98,18 @@
base::StringView s)
: phase(p), tgid(tg), name(std::move(n)), int_value(v), str_value(s) {}
- // Phase can be one of B, E, C, S, F.
+ // Phase can be one of B, E, C, S, F, I, N, T, U.
char phase = '\0';
uint32_t tgid = 0;
- // For phase = 'B' and phase = 'C' only.
+ // For phase = B, C, S, F, N, U, T, U.
base::StringView name;
- // For phase = 'C' (counter value) and 'B', 'F' (async cookie).
+ // For phase = C (counter value) and B, S, F, N, T, U (async cookie).
int64_t int_value = 0;
- // For phase = 'N' (instant on track)
+ // For phase = N, T, U (track name)
base::StringView str_value;
// Visible for unittesting.
@@ -107,17 +123,19 @@
};
// We have to handle trace_marker events of a few different types:
-// 1. some random text
-// 2. B|1636|pokeUserActivity
-// 3. E|1636
-// 4. C|1636|wq:monitor|0
-// 5. S|1636|frame_capture|123
-// 6. F|1636|frame_capture|456
+// 1. some random text
+// 2. B|1636|pokeUserActivity
+// 3. E|1636
+// 4. C|1636|wq:monitor|0
+// 5. S|1636|frame_capture|123
+// 6. F|1636|frame_capture|456
+// 7. C|3209|TransfersBytesPendingOnDisk-value|0|Blob
+// 8. I|4820|instant
+// 9. N|1938|track_name|instant_name
+// 10. T|1339|track_name|slice_name|789
+// 11. U|6890|track_name|slice_name|135
// Counters emitted by chromium can have a further "category group" appended
// ("Blob" in the example below). We ignore the category group.
-// 7. C|3209|TransfersBytesPendingOnDisk-value|0|Blob
-// 8. I|4820|instant
-// 9. N|1938|track_name|instant_name
inline SystraceParseResult ParseSystraceTracePoint(
base::StringView str_untrimmed,
SystraceTracePoint* out) {
@@ -219,6 +237,20 @@
out->int_value = *maybe_value;
return SystraceParseResult::kSuccess;
}
+ case 'T': // Begin of async slice on track.
+ case 'U': { // End of async slice on track.
+ auto f2_track_name = read_next_field();
+ auto f3_name = read_next_field();
+ auto maybe_cookie = base::StringToInt64(read_next_field().ToStdString());
+ if (PERFETTO_UNLIKELY(!has_tgid || f2_track_name.empty() ||
+ f3_name.empty() || !maybe_cookie)) {
+ return SystraceParseResult::kFailure;
+ }
+ out->name = f3_name;
+ out->str_value = f2_track_name;
+ out->int_value = *maybe_cookie;
+ return SystraceParseResult::kSuccess;
+ }
default:
if (str.find("trace_event_clock_sync:") == 0)
return SystraceParseResult::kUnsupported;
diff --git a/src/trace_processor/importers/systrace/systrace_parser_unittest.cc b/src/trace_processor/importers/systrace/systrace_parser_unittest.cc
index be0d801..07431c6 100644
--- a/src/trace_processor/importers/systrace/systrace_parser_unittest.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser_unittest.cc
@@ -108,6 +108,32 @@
Result::kUnsupported);
}
+TEST(SystraceParserTest, AsyncTrackEvents) {
+ SystraceTracePoint result{};
+ ASSERT_EQ(ParseSystraceTracePoint("T", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U", &result), Result::kFailure);
+
+ ASSERT_EQ(ParseSystraceTracePoint("T||test|test|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123|test||", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123||test|", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123|track|event|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("T|123|track|event|456", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::T(123, "track", "event", 456));
+
+ ASSERT_EQ(ParseSystraceTracePoint("U||test|test|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123|test||", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123||test|", &result), Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123|track|event|", &result),
+ Result::kFailure);
+ ASSERT_EQ(ParseSystraceTracePoint("U|123|track|event|456", &result),
+ Result::kSuccess);
+ EXPECT_EQ(result, SystraceTracePoint::U(123, "track", "event", 456));
+}
+
} // namespace
} // namespace systrace_utils
} // namespace trace_processor
diff --git a/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql b/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql
index f88ed0f..9a93741 100644
--- a/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql
+++ b/src/trace_processor/metrics/sql/android/android_sysui_cuj_surfaceflinger.sql
@@ -146,7 +146,7 @@
slice.ts + slice.dur AS ts_end
FROM slice
JOIN android_sysui_cuj_sf_main_thread_track main_track ON slice.track_id = main_track.id
- WHERE slice.dur > 0 AND slice.name = 'composite';
+ WHERE slice.dur > 0 AND slice.name GLOB 'composite*';
DROP VIEW IF EXISTS android_sysui_cuj_surfaceflinger_commit_composite_frames_in_cuj;
CREATE VIEW android_sysui_cuj_surfaceflinger_commit_composite_frames_in_cuj AS
diff --git a/test/trace_processor/parsing/android_async_slice.textproto b/test/trace_processor/atrace/android_async_slice.textproto
similarity index 100%
rename from test/trace_processor/parsing/android_async_slice.textproto
rename to test/trace_processor/atrace/android_async_slice.textproto
diff --git a/test/trace_processor/parsing/android_b2b_async_begin.textproto b/test/trace_processor/atrace/android_b2b_async_begin.textproto
similarity index 100%
rename from test/trace_processor/parsing/android_b2b_async_begin.textproto
rename to test/trace_processor/atrace/android_b2b_async_begin.textproto
diff --git a/test/trace_processor/parsing/android_b2b_async_begin_list_slices.out b/test/trace_processor/atrace/android_b2b_async_begin_list_slices.out
similarity index 100%
rename from test/trace_processor/parsing/android_b2b_async_begin_list_slices.out
rename to test/trace_processor/atrace/android_b2b_async_begin_list_slices.out
diff --git a/test/trace_processor/atrace/async_track_atrace.py b/test/trace_processor/atrace/async_track_atrace.py
new file mode 100644
index 0000000..121f6d3
--- /dev/null
+++ b/test/trace_processor/atrace/async_track_atrace.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+# 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.
+
+from os import sys, path
+
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_packet()
+trace.add_process(pid=1, ppid=0, cmdline="p1")
+trace.add_process(pid=2, ppid=1, cmdline="p2")
+
+trace.add_thread(tid=1, tgid=1, cmdline='p1', name='p1')
+trace.add_thread(tid=2, tgid=2, cmdline='p2', name='p2')
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_print(ts=50, tid=1, buf='T|1|track|ev|1024\n')
+trace.add_print(ts=55, tid=1, buf='T|1|track|ev|2048\n')
+trace.add_print(ts=60, tid=2, buf='T|2|track|ev|1024\n')
+trace.add_print(ts=65, tid=2, buf='U|2|track|ev|1024\n')
+trace.add_print(ts=70, tid=1, buf='U|1|track|ev|2048\n')
+trace.add_print(ts=75, tid=1, buf='U|1|track|ev|1024\n')
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/atrace/async_track_atrace_process_track_slices.out b/test/trace_processor/atrace/async_track_atrace_process_track_slices.out
new file mode 100644
index 0000000..3023fcf
--- /dev/null
+++ b/test/trace_processor/atrace/async_track_atrace_process_track_slices.out
@@ -0,0 +1,4 @@
+"ts","dur","pid","slice_name","track_name"
+50,25,1,"ev","track"
+55,15,1,"ev","track"
+60,5,2,"ev","track"
diff --git a/test/trace_processor/parsing/bad_print.systrace b/test/trace_processor/atrace/bad_print.systrace
similarity index 100%
rename from test/trace_processor/parsing/bad_print.systrace
rename to test/trace_processor/atrace/bad_print.systrace
diff --git a/test/trace_processor/parsing/bad_print.textproto b/test/trace_processor/atrace/bad_print.textproto
similarity index 100%
rename from test/trace_processor/parsing/bad_print.textproto
rename to test/trace_processor/atrace/bad_print.textproto
diff --git a/test/trace_processor/parsing/bad_print_systrace_list_slices.out b/test/trace_processor/atrace/bad_print_systrace_list_slices.out
similarity index 100%
rename from test/trace_processor/parsing/bad_print_systrace_list_slices.out
rename to test/trace_processor/atrace/bad_print_systrace_list_slices.out
diff --git a/test/trace_processor/parsing/bad_print_textproto_list_slices.out b/test/trace_processor/atrace/bad_print_textproto_list_slices.out
similarity index 100%
rename from test/trace_processor/parsing/bad_print_textproto_list_slices.out
rename to test/trace_processor/atrace/bad_print_textproto_list_slices.out
diff --git a/test/trace_processor/atrace/index b/test/trace_processor/atrace/index
new file mode 100644
index 0000000..32a8119
--- /dev/null
+++ b/test/trace_processor/atrace/index
@@ -0,0 +1,13 @@
+# Check error handling when parsing print events.
+bad_print.textproto ../common/list_slices.sql bad_print_textproto_list_slices.out
+bad_print.systrace ../common/list_slices.sql bad_print_systrace_list_slices.out
+instant_atrace.py instant_with_thread.sql instant_atrace_instant_with_thread.out
+instant_async_atrace.py instant_async.sql instant_async_atrace_instant_async.out
+
+# Match legacy Catapult behaviour when we see multiple S events b2b with the same cookie
+# name and upid.
+android_b2b_async_begin.textproto ../common/list_slices.sql android_b2b_async_begin_list_slices.out
+
+# Android userspace async slices
+android_async_slice.textproto ../common/process_track_slices.sql process_track_slices_android_async_slice.out
+async_track_atrace.py ../common/process_track_slices.sql async_track_atrace_process_track_slices.out
diff --git a/test/trace_processor/parsing/instant_async.sql b/test/trace_processor/atrace/instant_async.sql
similarity index 100%
rename from test/trace_processor/parsing/instant_async.sql
rename to test/trace_processor/atrace/instant_async.sql
diff --git a/test/trace_processor/parsing/instant_async_atrace.py b/test/trace_processor/atrace/instant_async_atrace.py
similarity index 100%
rename from test/trace_processor/parsing/instant_async_atrace.py
rename to test/trace_processor/atrace/instant_async_atrace.py
diff --git a/test/trace_processor/parsing/instant_async_atrace_instant_async.out b/test/trace_processor/atrace/instant_async_atrace_instant_async.out
similarity index 100%
rename from test/trace_processor/parsing/instant_async_atrace_instant_async.out
rename to test/trace_processor/atrace/instant_async_atrace_instant_async.out
diff --git a/test/trace_processor/parsing/instant_atrace.py b/test/trace_processor/atrace/instant_atrace.py
similarity index 100%
rename from test/trace_processor/parsing/instant_atrace.py
rename to test/trace_processor/atrace/instant_atrace.py
diff --git a/test/trace_processor/parsing/instant_atrace_instant_with_thread.out b/test/trace_processor/atrace/instant_atrace_instant_with_thread.out
similarity index 100%
rename from test/trace_processor/parsing/instant_atrace_instant_with_thread.out
rename to test/trace_processor/atrace/instant_atrace_instant_with_thread.out
diff --git a/test/trace_processor/parsing/instant_with_thread.sql b/test/trace_processor/atrace/instant_with_thread.sql
similarity index 100%
rename from test/trace_processor/parsing/instant_with_thread.sql
rename to test/trace_processor/atrace/instant_with_thread.sql
diff --git a/test/trace_processor/parsing/process_track_slices_android_async_slice.out b/test/trace_processor/atrace/process_track_slices_android_async_slice.out
similarity index 100%
rename from test/trace_processor/parsing/process_track_slices_android_async_slice.out
rename to test/trace_processor/atrace/process_track_slices_android_async_slice.out
diff --git a/test/trace_processor/parsing/list_slices.sql b/test/trace_processor/common/list_slices.sql
similarity index 96%
rename from test/trace_processor/parsing/list_slices.sql
rename to test/trace_processor/common/list_slices.sql
index 211ae89..55b0d72 100644
--- a/test/trace_processor/parsing/list_slices.sql
+++ b/test/trace_processor/common/list_slices.sql
@@ -1,2 +1,2 @@
SELECT ts, dur, name
-FROM slice
\ No newline at end of file
+FROM slice
diff --git a/test/trace_processor/parsing/process_track_slices.sql b/test/trace_processor/common/process_track_slices.sql
similarity index 100%
rename from test/trace_processor/parsing/process_track_slices.sql
rename to test/trace_processor/common/process_track_slices.sql
diff --git a/test/trace_processor/include_index b/test/trace_processor/include_index
index 593e338..29a7b41 100644
--- a/test/trace_processor/include_index
+++ b/test/trace_processor/include_index
@@ -1,3 +1,4 @@
+atrace/index
camera/index
chrome/index
cros/index
diff --git a/test/trace_processor/parsing/index b/test/trace_processor/parsing/index
index 4913f0b..9952dea 100644
--- a/test/trace_processor/parsing/index
+++ b/test/trace_processor/parsing/index
@@ -56,9 +56,6 @@
# Mm Event
../../data/mm_event.pb mm_event.sql mm_event.out
-# Android userspace async slices
-android_async_slice.textproto process_track_slices.sql process_track_slices_android_async_slice.out
-
# Check the systrace conversion code in the raw table.
# Print events
../../data/lmk_userspace.pb print_systrace.sql print_systrace_lmk_userspace.out
@@ -75,16 +72,6 @@
../../data/systrace.html systrace_html.sql systrace_html.out
../../data/trailing_empty.systrace sched_smoke.sql sched_smoke_trailing_empty.out
-# Check error handling when parsing print events.
-bad_print.textproto list_slices.sql bad_print_textproto_list_slices.out
-bad_print.systrace list_slices.sql bad_print_systrace_list_slices.out
-instant_atrace.py instant_with_thread.sql instant_atrace_instant_with_thread.out
-instant_async_atrace.py instant_async.sql instant_async_atrace_instant_async.out
-
-# Match legacy Catapult behaviour when we see multiple S events b2b with the same cookie
-# name and upid.
-android_b2b_async_begin.textproto list_slices.sql android_b2b_async_begin_list_slices.out
-
# LMK handling
kernel_lmk.py lmk.sql lmk_kernel_lmk.out
../../data/lmk_userspace.pb lmk.sql lmk_userspace_lmk.out
diff --git a/tools/install-build-deps b/tools/install-build-deps
index a9004f0..de21e94 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -231,7 +231,7 @@
Dependency(
'buildtools/android-unwinding',
'https://android.googlesource.com/platform/system/unwinding.git',
- 'b61aebb7f7afaad9b775a59dcd0ea6289fc4325a', 'all', 'all'),
+ '215644709bd7bbda4c05a9db4d55e96be61bcf64', 'all', 'all'),
Dependency('buildtools/android-logging',
'https://android.googlesource.com/platform/system/logging.git',
'7b36b566c9113fc703d68f76e8f40c0c2432481c', 'all', 'all'),
diff --git a/ui/src/assets/trace_info_page.scss b/ui/src/assets/trace_info_page.scss
index 84ee72f..a91dcf9 100644
--- a/ui/src/assets/trace_info_page.scss
+++ b/ui/src/assets/trace_info_page.scss
@@ -76,6 +76,10 @@
background-color: rgba(0, 0, 0, 0.04);
}
+ td.name {
+ min-width: 150px;
+ }
+
td {
font-family: var(--monospace-font);
font-size: 12px;
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index 8366f65..1f8ca17 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -15,7 +15,6 @@
import {Draft} from 'immer';
import {assertExists, assertTrue} from '../base/logging';
-import {randomColor} from '../common/colorizer';
import {RecordConfig} from '../controller/record_config_types';
import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from '../tracks/actual_frames/common';
import {ASYNC_SLICE_TRACK_KIND} from '../tracks/async_slices/common';
@@ -33,6 +32,7 @@
} from '../tracks/process_scheduling/common';
import {PROCESS_SUMMARY_TRACK} from '../tracks/process_summary/common';
+import {randomColor} from './colorizer';
import {createEmptyState} from './empty_state';
import {DEFAULT_VIEWING_OPTION, PERF_SAMPLES_KEY} from './flamegraph_util';
import {
@@ -134,11 +134,18 @@
return index;
}
+function generateNextId(draft: StateDraft): string {
+ const nextId = String(Number(draft.nextId) + 1);
+ draft.nextId = nextId;
+ return nextId;
+}
+
export const StateActions = {
openTraceFromFile(state: StateDraft, args: {file: File}): void {
clearTraceState(state);
- const id = `${state.nextId++}`;
+ const id = generateNextId(state);
+ state.currentEngineId = id;
state.engines[id] = {
id,
ready: false,
@@ -148,7 +155,8 @@
openTraceFromBuffer(state: StateDraft, args: PostedTrace): void {
clearTraceState(state);
- const id = `${state.nextId++}`;
+ const id = generateNextId(state);
+ state.currentEngineId = id;
state.engines[id] = {
id,
ready: false,
@@ -158,7 +166,8 @@
openTraceFromUrl(state: StateDraft, args: {url: string}): void {
clearTraceState(state);
- const id = `${state.nextId++}`;
+ const id = generateNextId(state);
+ state.currentEngineId = id;
state.engines[id] = {
id,
ready: false,
@@ -168,7 +177,8 @@
openTraceFromHttpRpc(state: StateDraft, _args: {}): void {
clearTraceState(state);
- const id = `${state.nextId++}`;
+ const id = generateNextId(state);
+ state.currentEngineId = id;
state.engines[id] = {
id,
ready: false,
@@ -198,7 +208,7 @@
addTracks(state: StateDraft, args: {tracks: AddTrackArgs[]}) {
args.tracks.forEach(track => {
- const id = track.id === undefined ? `${state.nextId++}` : track.id;
+ const id = track.id === undefined ? generateNextId(state) : track.id;
track.id = id;
state.tracks[id] = track as TrackState;
this.fillUiTrackIdByTraceTrackId(state, track as TrackState, id);
@@ -214,7 +224,7 @@
id?: string; engineId: string; kind: string; name: string;
trackGroup?: string; config: {}; trackKindPriority: TrackKindPriority;
}): void {
- const id = args.id !== undefined ? args.id : `${state.nextId++}`;
+ const id = args.id !== undefined ? args.id : generateNextId(state);
state.tracks[id] = {
id,
engineId: args.engineId,
@@ -252,7 +262,7 @@
addDebugTrack(state: StateDraft, args: {engineId: string, name: string}):
void {
if (state.debugTrackId !== undefined) return;
- const trackId = `${state.nextId++}`;
+ const trackId = generateNextId(state);
state.debugTrackId = trackId;
this.addTrack(state, {
id: trackId,
@@ -334,11 +344,11 @@
executeQuery(
state: StateDraft,
- args: {queryId: string; engineId: string; query: string}): void {
+ args: {queryId: string; query: string, engineId?: string}): void {
state.queries[args.queryId] = {
id: args.queryId,
- engineId: args.engineId,
query: args.query,
+ engineId: args.engineId
};
},
@@ -433,7 +443,7 @@
createPermalink(state: StateDraft, args: {isRecordingConfig: boolean}): void {
state.permalink = {
- requestId: `${state.nextId++}`,
+ requestId: generateNextId(state),
hash: undefined,
isRecordingConfig: args.isRecordingConfig
};
@@ -447,7 +457,7 @@
},
loadPermalink(state: StateDraft, args: {hash: string}): void {
- state.permalink = {requestId: `${state.nextId++}`, hash: args.hash};
+ state.permalink = {requestId: generateNextId(state), hash: args.hash};
},
clearPermalink(state: StateDraft, _: {}): void {
@@ -497,7 +507,7 @@
},
addNote(state: StateDraft, args: {timestamp: number, color: string}): void {
- const id = `${state.nextNoteId++}`;
+ const id = generateNextId(state);
state.notes[id] = {
noteType: 'DEFAULT',
id,
@@ -515,7 +525,7 @@
state.currentSelection.kind !== 'AREA') {
return;
}
- const id = args.persistent ? `${state.nextNoteId++}` : '0';
+ const id = args.persistent ? generateNextId(state) : '0';
const color = args.persistent ? args.color : '#344596';
state.notes[id] = {
noteType: 'AREA',
@@ -539,7 +549,7 @@
},
markArea(state: StateDraft, args: {area: Area, persistent: boolean}): void {
- const areaId = `${state.nextAreaId++}`;
+ const areaId = generateNextId(state);
assertTrue(args.area.endSec >= args.area.startSec);
state.areas[areaId] = {
id: areaId,
@@ -547,11 +557,11 @@
endSec: args.area.endSec,
tracks: args.area.tracks
};
- const id = args.persistent ? `${state.nextNoteId++}` : '0';
+ const noteId = args.persistent ? generateNextId(state) : '0';
const color = args.persistent ? randomColor() : '#344596';
- state.notes[id] = {
+ state.notes[noteId] = {
noteType: 'AREA',
- id,
+ id: noteId,
areaId,
color,
text: '',
@@ -768,7 +778,7 @@
},
selectArea(state: StateDraft, args: {area: Area}): void {
- const areaId = `${state.nextAreaId++}`;
+ const areaId = generateNextId(state);
assertTrue(args.area.endSec >= args.area.startSec);
state.areas[areaId] = {
id: areaId,
diff --git a/ui/src/common/actions_unittest.ts b/ui/src/common/actions_unittest.ts
index 53e8f65..66689b8 100644
--- a/ui/src/common/actions_unittest.ts
+++ b/ui/src/common/actions_unittest.ts
@@ -259,7 +259,6 @@
test('open trace', () => {
const state = createEmptyState();
- state.nextId = 100;
const recordConfig = state.recordConfig;
const after = produce(state, draft => {
StateActions.openTraceFromUrl(draft, {
@@ -268,7 +267,6 @@
});
const engineKeys = Object.keys(after.engines);
- expect(after.nextId).toBe(101);
expect(engineKeys.length).toBe(1);
expect((after.engines[engineKeys[0]].source as TraceUrlSource).url)
.toBe('https://example.com/bar');
@@ -316,15 +314,17 @@
test('setEngineReady', () => {
const state = createEmptyState();
- state.nextId = 100;
+ let latestEngineId = 'dummy value will be replaced';
+ state.currentEngineId = '100';
const after = produce(state, draft => {
StateActions.openTraceFromUrl(draft, {
url: 'https://example.com/bar',
});
+ latestEngineId = assertExists(draft.currentEngineId);
StateActions.setEngineReady(
- draft, {engineId: '100', ready: true, mode: 'WASM'});
+ draft, {engineId: latestEngineId, ready: true, mode: 'WASM'});
});
- expect(after.engines['100'].ready).toBe(true);
+ expect(after.engines[latestEngineId].ready).toBe(true);
});
test('sortTracksByPriority', () => {
diff --git a/ui/src/common/empty_state.ts b/ui/src/common/empty_state.ts
index ac287d2..c24567b 100644
--- a/ui/src/common/empty_state.ts
+++ b/ui/src/common/empty_state.ts
@@ -32,9 +32,8 @@
export function createEmptyState(): State {
return {
version: STATE_VERSION,
- nextId: 0,
- nextNoteId: 1, // 0 is reserved for ephemeral area marking.
- nextAreaId: 0,
+ currentEngineId: undefined,
+ nextId: '-1',
newEngineMode: 'USE_HTTP_RPC_IF_AVAILABLE',
engines: {},
traceTime: {...defaultTraceTime},
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index ef7edcd..6447767 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -80,7 +80,11 @@
// serialisation+deserialisation.
// 15: Added state for Pivot Table V2
// 16: Added boolean tracking if the flamegraph modal was dismissed
-export const STATE_VERSION = 16;
+// 17:
+// - add currentEngineId to track the id of the current engine
+// - remove nextNoteId, nextAreaId and use nextId as a unique counter for all
+// indexing except the indexing of the engines
+export const STATE_VERSION = 17;
export const SCROLLING_TRACK_GROUP = 'ScrollingTracks';
@@ -180,7 +184,7 @@
export interface QueryConfig {
id: string;
- engineId: string;
+ engineId?: string;
query: string;
}
@@ -393,9 +397,8 @@
// tslint:disable-next-line:no-any
[key: string]: any;
version: number;
- nextId: number;
- nextNoteId: number;
- nextAreaId: number;
+ currentEngineId?: string;
+ nextId: string;
/**
* State of the ConfigEditor.
diff --git a/ui/src/common/state_unittest.ts b/ui/src/common/state_unittest.ts
index 046f864..b26ac71 100644
--- a/ui/src/common/state_unittest.ts
+++ b/ui/src/common/state_unittest.ts
@@ -17,7 +17,7 @@
test('createEmptyState', () => {
const state: State = createEmptyState();
- expect(state.nextId).toEqual(0);
+ expect(state.currentEngineId).toEqual(undefined);
});
test('getContainingTrackId', () => {
diff --git a/ui/src/controller/permalink_controller.ts b/ui/src/controller/permalink_controller.ts
index cfb87dd..31a7010 100644
--- a/ui/src/controller/permalink_controller.ts
+++ b/ui/src/controller/permalink_controller.ts
@@ -26,6 +26,7 @@
saveTrace,
toSha256
} from '../common/upload_utils';
+import {globals as frontendGlobals} from '../frontend/globals';
import {publishConversionJobStatusUpdate} from '../frontend/publish';
import {Router} from '../frontend/router';
@@ -120,7 +121,7 @@
if (isRecordingConfig) {
uploadState = globals.state.recordConfig;
} else {
- const engine = assertExists(Object.values(globals.state.engines)[0]);
+ const engine = assertExists(frontendGlobals.getCurrentEngine());
let dataToUpload: File|ArrayBuffer|undefined = undefined;
let traceName = `trace ${engine.id}`;
if (engine.source.type === 'FILE') {
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index fb40021..62e9e59 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -186,6 +186,16 @@
// Create a QueryController for each query.
for (const queryId of Object.keys(globals.state.queries)) {
+ // If the expected engineId was not specified in the query, we
+ // assume it's `state.currentEngineId`. The engineId is not specified
+ // for instances with queries created prior to the creation of the
+ // first engine.
+ const expectedEngineId = globals.state.queries[queryId].engineId ||
+ frontendGlobals.state.currentEngineId;
+ // Check that we are executing the query on the correct engine.
+ if (expectedEngineId !== engine.id) {
+ continue;
+ }
const queryArgs: QueryControllerArgs = { queryId, engine };
childControllers.push(Child(queryId, QueryController, queryArgs));
}
diff --git a/ui/src/frontend/analyze_page.ts b/ui/src/frontend/analyze_page.ts
index c464651..cd9e05e 100644
--- a/ui/src/frontend/analyze_page.ts
+++ b/ui/src/frontend/analyze_page.ts
@@ -45,8 +45,7 @@
query = query.substring(selectionStart, selectionEnd);
}
if (!query) return;
- globals.dispatch(
- Actions.executeQuery({engineId: '0', queryId: QUERY_ID, query}));
+ globals.dispatch(Actions.executeQuery({queryId: QUERY_ID, query}));
}
if (event.code === 'Tab') {
diff --git a/ui/src/frontend/error_dialog.ts b/ui/src/frontend/error_dialog.ts
index aa763bd..fa3f223 100644
--- a/ui/src/frontend/error_dialog.ts
+++ b/ui/src/frontend/error_dialog.ts
@@ -14,6 +14,7 @@
import * as m from 'mithril';
+import {assertExists} from '../base/logging';
import {TraceUrlSource} from '../common/state';
import {saveTrace} from '../common/upload_utils';
@@ -74,7 +75,7 @@
const errTitle = errLog.split('\n', 1)[0].substr(0, 80);
const userDescription = '';
let checked = false;
- const engine = Object.values(globals.state.engines)[0];
+ const engine = globals.getCurrentEngine();
const shareTraceSection: m.Vnode[] = [];
if (isShareable() && !urlExists()) {
@@ -83,7 +84,7 @@
checked,
oninput: (ev: InputEvent) => {
checked = (ev.target as HTMLInputElement).checked;
- if (checked && engine.source.type === 'FILE') {
+ if (checked && engine && engine.source.type === 'FILE') {
saveTrace(engine.source.file).then(url => {
const errMessage = createErrorMessage(errLog, checked, url);
renderModal(
@@ -152,7 +153,7 @@
// If there is a trace URL to share, we don't have to show the upload checkbox.
function urlExists() {
- const engine = Object.values(globals.state.engines)[0];
+ const engine = globals.getCurrentEngine();
return engine !== undefined &&
(engine.source.type === 'ARRAY_BUFFER' || engine.source.type === 'URL') &&
engine.source.url !== undefined;
@@ -160,11 +161,12 @@
function createErrorMessage(errLog: string, checked: boolean, url?: string) {
let errMessage = '';
- const engine = Object.values(globals.state.engines)[0];
+ const engine = globals.getCurrentEngine();
if (checked && url !== undefined) {
errMessage += `Trace: ${url}`;
} else if (urlExists()) {
- errMessage += `Trace: ${(engine.source as TraceUrlSource).url}`;
+ errMessage +=
+ `Trace: ${(assertExists(engine).source as TraceUrlSource).url}`;
} else {
errMessage += 'To assist with debugging please attach or link to the ' +
'trace you were viewing.';
diff --git a/ui/src/frontend/flamegraph_panel.ts b/ui/src/frontend/flamegraph_panel.ts
index 368ab32..866ed87 100644
--- a/ui/src/frontend/flamegraph_panel.ts
+++ b/ui/src/frontend/flamegraph_panel.ts
@@ -248,7 +248,7 @@
}
downloadPprof() {
- const engine = Object.values(globals.state.engines)[0];
+ const engine = globals.getCurrentEngine();
if (!engine) return;
getCurrentTrace()
.then(file => {
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 71e2a34..a7662bf 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -24,7 +24,7 @@
import {Engine} from '../common/engine';
import {MetricResult} from '../common/metric_data';
import {CurrentSearchResults, SearchSummary} from '../common/search_data';
-import {CallsiteInfo, State} from '../common/state';
+import {CallsiteInfo, EngineConfig, State} from '../common/state';
import {fromNs, toNs} from '../common/time';
import {Analytics, initAnalytics} from './analytics';
@@ -514,6 +514,13 @@
return resolution;
}
+ getCurrentEngine(): EngineConfig|undefined {
+ if (!this.state.currentEngineId) {
+ return undefined;
+ }
+ return this.state.engines[this.state.currentEngineId];
+ }
+
makeSelection(action: DeferredAction<{}>, tabToOpen = 'current_selection') {
// A new selection should cancel the current search selection.
globals.dispatch(Actions.setSearchIndex({index: -1}));
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index 15ad0cf..c0977ce 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -323,9 +323,8 @@
// Don't allow postMessage or opening trace from route when the user says
// that they want to reuse the already loaded trace in trace processor.
- const values = Object.values(globals.state.engines);
- if (values.length > 0 &&
- globals.state.engines[values.length - 1].source.type === 'HTTP_RPC') {
+ const engine = globals.getCurrentEngine();
+ if (engine && engine.source.type === 'HTTP_RPC') {
return;
}
diff --git a/ui/src/frontend/pivot_table_redux.ts b/ui/src/frontend/pivot_table_redux.ts
index 2bdae1b..262ebcf 100644
--- a/ui/src/frontend/pivot_table_redux.ts
+++ b/ui/src/frontend/pivot_table_redux.ts
@@ -15,7 +15,6 @@
*/
import * as m from 'mithril';
-
import {GenericSet} from '../base/generic_set';
import {sqliteString} from '../base/string_utils';
import {Actions} from '../common/actions';
@@ -171,7 +170,6 @@
// TODO(ddrone): the UI of running query as if it was a canned or
// custom query is a temporary one, replace with a proper UI.
globals.dispatch(Actions.executeQuery({
- engineId: '0',
queryId: 'command',
query,
}));
diff --git a/ui/src/frontend/record_config.ts b/ui/src/frontend/record_config.ts
index 847a270..a200b47 100644
--- a/ui/src/frontend/record_config.ts
+++ b/ui/src/frontend/record_config.ts
@@ -195,12 +195,8 @@
recordTargetOS: string|null;
constructor() {
- this.recordTargetOS = null;
- const savedTarget =
+ this.recordTargetOS =
window.localStorage.getItem(LOCAL_STORAGE_RECORD_TARGET_OS_KEY);
- if (typeof savedTarget === 'string') {
- this.recordTargetOS = savedTarget;
- }
}
get(): string|null {
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index 653ee61..e33f333 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -113,7 +113,6 @@
return (e: Event) => {
e.preventDefault();
globals.dispatch(Actions.executeQuery({
- engineId: '0',
queryId: 'command',
query,
}));
@@ -124,7 +123,7 @@
return (e: Event) => {
e.preventDefault();
globals.dispatch(Actions.addDebugTrack({
- engineId: Object.keys(globals.state.engines)[0],
+ engineId: assertExists(globals.state.currentEngineId),
name: 'Debug Slices',
}));
};
@@ -355,7 +354,7 @@
export async function getCurrentTrace(): Promise<Blob> {
// Caller must check engine exists.
- const engine = assertExists(Object.values(globals.state.engines)[0]);
+ const engine = assertExists(globals.getCurrentEngine());
const src = engine.source;
if (src.type === 'ARRAY_BUFFER') {
return new Blob([src.buffer]);
@@ -411,8 +410,7 @@
}
export function isTraceLoaded(): boolean {
- const engine = Object.values(globals.state.engines)[0];
- return engine !== undefined;
+ return globals.getCurrentEngine() !== undefined;
}
function openTraceUrl(url: string): (e: Event) => void {
@@ -539,7 +537,7 @@
function shareTrace(e: Event) {
e.preventDefault();
- const engine = assertExists(Object.values(globals.state.engines)[0]);
+ const engine = assertExists(globals.getCurrentEngine());
const traceUrl = (engine.source as (TraceArrayBufferSource)).url || '';
// If the trace is not shareable (has been pushed via postMessage()) but has
@@ -579,7 +577,7 @@
if (!isDownloadable() || !isTraceLoaded()) return;
globals.logging.logEvent('Trace Actions', 'Download trace');
- const engine = Object.values(globals.state.engines)[0];
+ const engine = globals.getCurrentEngine();
if (!engine) return;
let url = '';
let fileName = `trace${TRACE_SUFFIX}`;
diff --git a/ui/src/frontend/slice_panel.ts b/ui/src/frontend/slice_panel.ts
index 1f649c6..65beeb2 100644
--- a/ui/src/frontend/slice_panel.ts
+++ b/ui/src/frontend/slice_panel.ts
@@ -17,6 +17,22 @@
import {globals, SliceDetails} from './globals';
import {Panel} from './panel';
+// To display process or thread, we want to concatenate their name with ID, but
+// either can be undefined and all the cases need to be considered carefully to
+// avoid `undefined undefined` showing up in the UI. This function does such
+// concatenation.
+//
+// Result can be undefined if both name and process are, in this case result is
+// not going to be displayed in the UI.
+function getDisplayName(name: string|undefined, id: number|undefined): string|
+ undefined {
+ if (name === undefined) {
+ return id === undefined ? undefined : `${id}`;
+ } else {
+ return id === undefined ? name : `${name} ${id}`;
+ }
+}
+
export abstract class SlicePanel extends Panel {
protected computeDuration(ts: number, dur: number): string {
return toNs(dur) === -1 ?
@@ -26,8 +42,8 @@
protected getProcessThreadDetails(sliceInfo: SliceDetails) {
return new Map<string, string|undefined>([
- ['Thread', `${sliceInfo.threadName} ${sliceInfo.tid}`],
- ['Process', `${sliceInfo.processName} ${sliceInfo.pid}`],
+ ['Thread', getDisplayName(sliceInfo.threadName, sliceInfo.tid)],
+ ['Process', getDisplayName(sliceInfo.processName, sliceInfo.pid)],
['User ID', sliceInfo.uid ? String(sliceInfo.uid) : undefined],
['Package name', sliceInfo.packageName],
[
diff --git a/ui/src/frontend/topbar.ts b/ui/src/frontend/topbar.ts
index 9cb29bf..d816249 100644
--- a/ui/src/frontend/topbar.ts
+++ b/ui/src/frontend/topbar.ts
@@ -15,7 +15,6 @@
import * as m from 'mithril';
import {Actions} from '../common/actions';
-import {EngineConfig} from '../common/state';
import * as version from '../gen/perfetto_version';
import {globals} from './globals';
@@ -77,8 +76,8 @@
return;
}
if (mode === COMMAND && key === 'Enter') {
- globals.dispatch(Actions.executeQuery(
- {engineId: '0', queryId: 'command', query: txt.value}));
+ globals.dispatch(
+ Actions.executeQuery({queryId: 'command', query: txt.value}));
}
}
@@ -176,9 +175,9 @@
loadingAnimation() {
if (this.progressBar === undefined) return;
- const engine: EngineConfig = globals.state.engines['0'];
- if ((engine !== undefined && !engine.ready) ||
- globals.numQueuedQueries > 0 || taskTracker.hasPendingTasks()) {
+ const engine = globals.getCurrentEngine();
+ if ((engine && !engine.ready) || globals.numQueuedQueries > 0 ||
+ taskTracker.hasPendingTasks()) {
this.progressBar.classList.add('progress-anim');
} else {
this.progressBar.classList.remove('progress-anim');
diff --git a/ui/src/frontend/trace_attrs.ts b/ui/src/frontend/trace_attrs.ts
index 9cc7292..5162469 100644
--- a/ui/src/frontend/trace_attrs.ts
+++ b/ui/src/frontend/trace_attrs.ts
@@ -19,11 +19,10 @@
}
export function isDownloadable() {
- const engine = Object.values(globals.state.engines)[0];
+ const engine = globals.getCurrentEngine();
if (engine && engine.source.type === 'ARRAY_BUFFER' &&
engine.source.localOnly) {
return false;
}
- if (engine && engine.source.type === 'HTTP_RPC') return false;
- return true;
+ return !(engine && engine.source.type === 'HTTP_RPC');
}
\ No newline at end of file
diff --git a/ui/src/frontend/trace_info_page.ts b/ui/src/frontend/trace_info_page.ts
index b1ba4d3..2758bb9 100644
--- a/ui/src/frontend/trace_info_page.ts
+++ b/ui/src/frontend/trace_info_page.ts
@@ -40,7 +40,6 @@
if (!this.queryDispatched) {
this.queryDispatched = true;
globals.dispatch(Actions.executeQuery({
- engineId: '0',
queryId: attrs.queryId,
query: `select name, value, cast(ifnull(idx, '') as text) as idx,
description, severity, source from stats
@@ -64,7 +63,7 @@
const idx = row.idx !== '' ? `[${row.idx}]` : '';
tableRows.push(m(
'tr',
- m('td', {title: row.description}, `${row.name}${idx}`, help),
+ m('td.name', {title: row.description}, `${row.name}${idx}`, help),
m('td', `${row.value}`),
m('td', `${row.severity} (${row.source})`),
));
@@ -103,7 +102,6 @@
if (!this.queryDispatched) {
this.queryDispatched = true;
globals.dispatch(Actions.executeQuery({
- engineId: '0',
queryId: this.QUERY_ID,
query: `select name, ifnull(str_value, cast(int_value as text)) as value
from metadata order by name`,
@@ -119,7 +117,7 @@
for (const row of resp.rows) {
tableRows.push(m(
'tr',
- m('td', `${row.name}`),
+ m('td.name', `${row.name}`),
m('td', `${row.value}`),
));
}
@@ -144,7 +142,6 @@
if (!this.queryDispatched) {
this.queryDispatched = true;
globals.dispatch(Actions.executeQuery({
- engineId: '0',
queryId: this.QUERY_ID,
query: `select package_name, version_code, debuggable,
profileable_from_shell from package_list`,
@@ -160,7 +157,7 @@
for (const row of resp.rows) {
tableRows.push(m(
'tr',
- m('td', `${row.package_name}`),
+ m('td.name', `${row.package_name}`),
m('td', `${row.version_code}`),
m('td',
`${row.debuggable ? 'debuggable' : ''} ${