Merge "Allow android.polled_state to... poll."
diff --git a/gn/standalone/write_ui_dist_file_map.py b/gn/standalone/write_ui_dist_file_map.py
index 8ea5aff..999bea5 100644
--- a/gn/standalone/write_ui_dist_file_map.py
+++ b/gn/standalone/write_ui_dist_file_map.py
@@ -30,7 +30,6 @@
import argparse
import base64
import hashlib
-import multiprocessing
import os
import sys
@@ -60,15 +59,14 @@
parser.add_argument('file_list', nargs=argparse.REMAINDER)
args = parser.parse_args()
- # Compute the hash of each file (in parallel).
- pool = multiprocessing.Pool(multiprocessing.cpu_count() * 2)
- digests = dict(pool.map(hash_file, args.file_list))
+ # Compute the hash of each file.
+ digests = dict(map(hash_file, args.file_list))
contents = '// __generated_by %s\n' % __file__
contents += 'export const UI_DIST_MAP = {\n'
contents += ' files: {\n'
strip = args.strip + ('' if args.strip[-1] == os.path.sep else os.path.sep)
- for fname, digest in digests.iteritems():
+ for fname, digest in digests.items():
if not fname.startswith(strip):
raise Exception('%s must start with %s (--strip arg)' % (fname, strip))
fname = fname[len(strip):]
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index d0e8ad5..ef15834 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -740,7 +740,7 @@
{kTimestamp2, 0, track2, cat_id, name_id, 0, 0, 0});
// Async event track.
- context_.track_tracker->ReserveDescriptorChildTrack(1234, 0);
+ context_.track_tracker->ReserveDescriptorChildTrack(1234, 0, kNullStringId);
TrackId track3 = *context_.track_tracker->GetDescriptorTrack(1234);
context_.args_tracker->Flush(); // Flush track args.
context_.storage->mutable_slice_table()->Insert(
diff --git a/src/trace_processor/importers/common/track_tracker.cc b/src/trace_processor/importers/common/track_tracker.cc
index d4e357f..788296d 100644
--- a/src/trace_processor/importers/common/track_tracker.cc
+++ b/src/trace_processor/importers/common/track_tracker.cc
@@ -190,11 +190,13 @@
}
void TrackTracker::ReserveDescriptorProcessTrack(uint64_t uuid,
+ StringId name,
uint32_t pid,
int64_t timestamp) {
DescriptorTrackReservation reservation;
reservation.min_timestamp = timestamp;
reservation.pid = pid;
+ reservation.name = name;
std::map<uint64_t, DescriptorTrackReservation>::iterator it;
bool inserted;
@@ -219,6 +221,7 @@
void TrackTracker::ReserveDescriptorThreadTrack(uint64_t uuid,
uint64_t parent_uuid,
+ StringId name,
uint32_t pid,
uint32_t tid,
int64_t timestamp) {
@@ -227,6 +230,7 @@
reservation.parent_uuid = parent_uuid;
reservation.pid = pid;
reservation.tid = tid;
+ reservation.name = name;
std::map<uint64_t, DescriptorTrackReservation>::iterator it;
bool inserted;
@@ -251,6 +255,7 @@
void TrackTracker::ReserveDescriptorCounterTrack(uint64_t uuid,
uint64_t parent_uuid,
+ StringId name,
StringId category,
int64_t unit_multiplier,
bool is_incremental,
@@ -258,6 +263,7 @@
DescriptorTrackReservation reservation;
reservation.parent_uuid = parent_uuid;
reservation.is_counter = true;
+ reservation.name = name;
reservation.category = category;
reservation.unit_multiplier = unit_multiplier;
reservation.is_incremental = is_incremental;
@@ -282,9 +288,11 @@
}
void TrackTracker::ReserveDescriptorChildTrack(uint64_t uuid,
- uint64_t parent_uuid) {
+ uint64_t parent_uuid,
+ StringId name) {
DescriptorTrackReservation reservation;
reservation.parent_uuid = parent_uuid;
+ reservation.name = name;
std::map<uint64_t, DescriptorTrackReservation>::iterator it;
bool inserted;
@@ -326,6 +334,17 @@
uint64_t uuid,
const DescriptorTrackReservation& reservation,
std::vector<uint64_t>* descendent_uuids) {
+ auto set_track_name_and_return = [this, &reservation](TrackId track_id) {
+ // Initialize the track name here, so that, if a name was given in the
+ // reservation, it is set immediately after resolution takes place.
+ if (reservation.name != kNullStringId) {
+ auto* tracks = context_->storage->mutable_track_table();
+ tracks->mutable_name()->Set(*tracks->id().IndexOf(track_id),
+ reservation.name);
+ }
+ return track_id;
+ };
+
static constexpr size_t kMaxAncestors = 10;
// Try to resolve any parent tracks recursively, too.
@@ -393,7 +412,7 @@
descriptor_uuids_by_utid_[utid] = uuid;
}
- return InternThreadTrack(utid);
+ return set_track_name_and_return(InternThreadTrack(utid));
}
if (reservation.pid) {
@@ -419,7 +438,7 @@
descriptor_uuids_by_upid_[upid] = uuid;
}
- return InternProcessTrack(upid);
+ return set_track_name_and_return(InternProcessTrack(upid));
}
base::Optional<TrackId> track_id;
@@ -506,7 +525,7 @@
if (reservation.category != kNullStringId) {
args.AddArg(category_key_, Variadic::String(reservation.category));
}
- return *track_id;
+ return set_track_name_and_return(*track_id);
}
TrackId TrackTracker::GetOrCreateDefaultDescriptorTrack() {
@@ -518,13 +537,9 @@
return *track_id;
// Otherwise reserve a new track and resolve it.
- ReserveDescriptorChildTrack(kDefaultDescriptorTrackUuid, /*parent_uuid=*/0);
- track_id = GetDescriptorTrack(kDefaultDescriptorTrackUuid);
-
- auto* tracks = context_->storage->mutable_track_table();
- tracks->mutable_name()->Set(*tracks->id().IndexOf(*track_id),
+ ReserveDescriptorChildTrack(kDefaultDescriptorTrackUuid, /*parent_uuid=*/0,
default_descriptor_track_name_);
- return *track_id;
+ return *GetDescriptorTrack(kDefaultDescriptorTrackUuid);
}
TrackId TrackTracker::GetOrCreateTriggerTrack() {
diff --git a/src/trace_processor/importers/common/track_tracker.h b/src/trace_processor/importers/common/track_tracker.h
index 2f3b59c..c4bd3c7 100644
--- a/src/trace_processor/importers/common/track_tracker.h
+++ b/src/trace_processor/importers/common/track_tracker.h
@@ -71,6 +71,7 @@
// upon the first call to GetDescriptorTrack() with the same |uuid|. At this
// time, |pid| will also be resolved to a |upid|.
void ReserveDescriptorProcessTrack(uint64_t uuid,
+ StringId name,
uint32_t pid,
int64_t timestamp);
@@ -84,6 +85,7 @@
// time, |pid| will also be resolved to a |upid|.
void ReserveDescriptorThreadTrack(uint64_t uuid,
uint64_t parent_uuid,
+ StringId name,
uint32_t pid,
uint32_t tid,
int64_t timestamp);
@@ -97,7 +99,9 @@
// the same |uuid|. If |parent_uuid| is 0, the track will become a global
// track. Otherwise, it will become a new track of the same type as its parent
// track.
- void ReserveDescriptorChildTrack(uint64_t uuid, uint64_t parent_uuid);
+ void ReserveDescriptorChildTrack(uint64_t uuid,
+ uint64_t parent_uuid,
+ StringId name);
// Associate a counter-type TrackDescriptor track identified by the given
// |uuid| with a parent track (usually a process or thread track). This is
@@ -117,6 +121,7 @@
// process/thread as its parent track.
void ReserveDescriptorCounterTrack(uint64_t uuid,
uint64_t parent_uuid,
+ StringId name,
StringId category,
int64_t unit_multiplier,
bool is_incremental,
@@ -217,6 +222,7 @@
base::Optional<uint32_t> pid;
base::Optional<uint32_t> tid;
int64_t min_timestamp = 0; // only set if |pid| and/or |tid| is set.
+ StringId name = kNullStringId;
// For counter tracks.
bool is_counter = false;
@@ -229,8 +235,8 @@
// Whether |other| is a valid descriptor for this track reservation. A track
// should always remain nested underneath its original parent.
bool IsForSameTrack(const DescriptorTrackReservation& other) {
- // Note that |min_timestamp| and |last_value| are ignored for this
- // comparison.
+ // Note that |min_timestamp|, |latest_value|, and |name| are ignored for
+ // this comparison.
return std::tie(parent_uuid, pid, tid, is_counter, category,
unit_multiplier, is_incremental, packet_sequence_id) ==
std::tie(other.parent_uuid, pid, tid, is_counter, category,
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 81c9982..7d76854 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -54,6 +54,7 @@
#include "protos/perfetto/trace/sys_stats/sys_stats.pbzero.h"
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "protos/perfetto/trace/track_event/counter_descriptor.pbzero.h"
#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
#include "protos/perfetto/trace/track_event/log_message.pbzero.h"
#include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
@@ -1444,6 +1445,110 @@
EXPECT_EQ(storage_->thread_slices().thread_instruction_deltas()[1], 0);
}
+TEST_F(ProtoTraceParserTest, TrackEventWithResortedCounterDescriptor) {
+ context_.sorter.reset(new TraceSorter(
+ CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
+
+ // Descriptors with timestamps after the event below. They will be tokenized
+ // in the order they appear here, but then resorted before parsing to appear
+ // after the events below.
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ packet->set_incremental_state_cleared(true);
+ packet->set_timestamp(3000);
+ auto* track_desc = packet->set_track_descriptor();
+ track_desc->set_uuid(1);
+ auto* thread_desc = track_desc->set_thread();
+ thread_desc->set_pid(5);
+ thread_desc->set_tid(1);
+ thread_desc->set_thread_name("t1");
+ // Default to track for "t1" and an extra counter for thread time.
+ auto* track_event_defaults =
+ packet->set_trace_packet_defaults()->set_track_event_defaults();
+ track_event_defaults->set_track_uuid(1);
+ // Thread-time counter track defined below.
+ track_event_defaults->add_extra_counter_track_uuids(10);
+ }
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ packet->set_timestamp(3000);
+ auto* track_desc = packet->set_track_descriptor();
+ track_desc->set_uuid(10);
+ track_desc->set_parent_uuid(1);
+ auto* counter = track_desc->set_counter();
+ counter->set_type(
+ protos::pbzero::CounterDescriptor::COUNTER_THREAD_TIME_NS);
+ counter->set_unit_multiplier(1000); // provided in us.
+ counter->set_is_incremental(true);
+ }
+ {
+ // Event with timestamps before the descriptors above. The thread time
+ // counter values should still be imported as counter values and as args for
+ // JSON export. Should appear on default track "t1" with
+ // extra_counter_values for "c1".
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ packet->set_sequence_flags(
+ protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+ packet->set_timestamp(1000);
+ auto* event = packet->set_track_event();
+ event->add_categories("cat1");
+ event->set_name("ev1");
+ event->set_type(protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN);
+ event->add_extra_counter_values(1000); // absolute: 1000000.
+ }
+ {
+ // End for "ev1".
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ packet->set_timestamp(1100);
+ auto* event = packet->set_track_event();
+ event->set_type(protos::pbzero::TrackEvent::TYPE_SLICE_END);
+ event->add_extra_counter_values(10); // absolute: 1010000.
+ }
+
+ EXPECT_CALL(*process_, UpdateThread(1, 5)).WillRepeatedly(Return(1));
+
+ tables::ThreadTable::Row t1(16);
+ t1.upid = 1u;
+ storage_->mutable_thread_table()->Insert(t1);
+
+ Tokenize();
+
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+
+ InSequence in_sequence; // Below slices should be sorted by timestamp.
+
+ EXPECT_CALL(*event_,
+ PushCounter(1000, testing::DoubleEq(1000000), TrackId{1}));
+ EXPECT_CALL(*slice_, Begin(1000, TrackId{0}, cat_1, ev_1, _))
+ .WillOnce(Return(0u));
+
+ EXPECT_CALL(*event_,
+ PushCounter(1100, testing::DoubleEq(1010000), TrackId{1}));
+ EXPECT_CALL(*slice_, End(1100, TrackId{0}, kNullStringId, kNullStringId, _))
+ .WillOnce(Return(0u));
+
+ EXPECT_CALL(*process_,
+ SetThreadNameIfUnset(1u, storage_->InternString("t1")));
+
+ context_.sorter->ExtractEventsForced();
+
+ // First track is thread time track, second is "t1".
+ EXPECT_EQ(storage_->track_table().row_count(), 2u);
+ EXPECT_EQ(storage_->thread_track_table().row_count(), 1u);
+ EXPECT_EQ(storage_->thread_track_table().utid()[0], 1u);
+
+ // Counter values should also be imported into thread slices.
+ EXPECT_EQ(storage_->thread_slices().slice_count(), 1u);
+ EXPECT_EQ(storage_->thread_slices().slice_ids()[0], 0u);
+ EXPECT_EQ(storage_->thread_slices().thread_timestamp_ns()[0], 1000000);
+ EXPECT_EQ(storage_->thread_slices().thread_duration_ns()[0], 10000);
+}
+
TEST_F(ProtoTraceParserTest, TrackEventWithoutIncrementalStateReset) {
context_.sorter.reset(new TraceSorter(
CreateParser(), std::numeric_limits<int64_t>::max() /*window size*/));
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 7bef66f..e432dbb 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -283,7 +283,7 @@
track_tracker->GetDescriptorTrack(track_uuid_);
if (!opt_track_id) {
track_tracker->ReserveDescriptorChildTrack(track_uuid_,
- /*parent_uuid=*/0);
+ /*parent_uuid=*/0, name_id_);
opt_track_id = track_tracker->GetDescriptorTrack(track_uuid_);
}
track_id_ = *opt_track_id;
@@ -1272,6 +1272,7 @@
ParseCounterDescriptor(track_id, decoder.counter());
}
+ // Override the name with the most recent name seen (after sorting by ts).
if (decoder.has_name()) {
auto* tracks = context_->storage->mutable_track_table();
StringId name_id = context_->storage->InternString(decoder.name());
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.cc b/src/trace_processor/importers/proto/track_event_tokenizer.cc
index 165eeff..ec5630d 100644
--- a/src/trace_processor/importers/proto/track_event_tokenizer.cc
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.cc
@@ -40,8 +40,16 @@
namespace perfetto {
namespace trace_processor {
+namespace {
+using protos::pbzero::CounterDescriptor;
+}
+
TrackEventTokenizer::TrackEventTokenizer(TraceProcessorContext* context)
- : context_(context) {}
+ : context_(context),
+ counter_name_thread_time_id_(
+ context_->storage->InternString("thread_time")),
+ counter_name_thread_instruction_count_id_(
+ context_->storage->InternString("thread_instruction_count")) {}
ModuleResult TrackEventTokenizer::TokenizeTrackDescriptorPacket(
PacketSequenceState* state,
@@ -57,6 +65,10 @@
return ModuleResult::Handled();
}
+ StringId name_id = kNullStringId;
+ if (track.has_name())
+ name_id = context_->storage->InternString(track.name());
+
if (track.has_thread()) {
protos::pbzero::ThreadDescriptor::Decoder thread(track.thread());
@@ -73,7 +85,8 @@
}
context_->track_tracker->ReserveDescriptorThreadTrack(
- track.uuid(), track.parent_uuid(), static_cast<uint32_t>(thread.pid()),
+ track.uuid(), track.parent_uuid(), name_id,
+ static_cast<uint32_t>(thread.pid()),
static_cast<uint32_t>(thread.tid()), packet_timestamp);
} else if (track.has_process()) {
protos::pbzero::ProcessDescriptor::Decoder process(track.process());
@@ -86,7 +99,8 @@
}
context_->track_tracker->ReserveDescriptorProcessTrack(
- track.uuid(), static_cast<uint32_t>(process.pid()), packet_timestamp);
+ track.uuid(), name_id, static_cast<uint32_t>(process.pid()),
+ packet_timestamp);
} else if (track.has_counter()) {
protos::pbzero::CounterDescriptor::Decoder counter(track.counter());
@@ -105,13 +119,32 @@
}
}
+ // TODO(eseckler): Intern counter tracks for specific counter types like
+ // thread time, so that the same counter can be referred to from tracks with
+ // different uuids. (Chrome may emit thread time values on behalf of other
+ // threads, in which case it has to use absolute values on a different
+ // track_uuid. Right now these absolute values are imported onto a separate
+ // counter track than the other thread's regular thread time values.)
+ if (name_id == kNullStringId) {
+ switch (counter.type()) {
+ case CounterDescriptor::COUNTER_UNSPECIFIED:
+ break;
+ case CounterDescriptor::COUNTER_THREAD_TIME_NS:
+ name_id = counter_name_thread_time_id_;
+ break;
+ case CounterDescriptor::COUNTER_THREAD_INSTRUCTION_COUNT:
+ name_id = counter_name_thread_instruction_count_id_;
+ break;
+ }
+ }
+
context_->track_tracker->ReserveDescriptorCounterTrack(
- track.uuid(), track.parent_uuid(), category_id,
+ track.uuid(), track.parent_uuid(), name_id, category_id,
counter.unit_multiplier(), counter.is_incremental(),
packet.trusted_packet_sequence_id());
} else {
- context_->track_tracker->ReserveDescriptorChildTrack(track.uuid(),
- track.parent_uuid());
+ context_->track_tracker->ReserveDescriptorChildTrack(
+ track.uuid(), track.parent_uuid(), name_id);
}
// Let ProtoTraceTokenizer forward the packet to the parser.
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.h b/src/trace_processor/importers/proto/track_event_tokenizer.h
index 0f914db..6657a48 100644
--- a/src/trace_processor/importers/proto/track_event_tokenizer.h
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.h
@@ -61,6 +61,9 @@
const protos::pbzero::ThreadDescriptor_Decoder&);
TraceProcessorContext* context_;
+
+ const StringId counter_name_thread_time_id_;
+ const StringId counter_name_thread_instruction_count_id_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/metrics/android/android_startup.sql b/src/trace_processor/metrics/android/android_startup.sql
index 944902d..3da0539 100644
--- a/src/trace_processor/metrics/android/android_startup.sql
+++ b/src/trace_processor/metrics/android/android_startup.sql
@@ -222,8 +222,8 @@
SELECT AndroidStartupMetric_HscMetrics(
'full_startup', (
SELECT AndroidStartupMetric_Slice(
- 'dur_ns', dur,
- 'dur_ms', dur / 1e6
+ 'dur_ns', hsc_based_startup_times.ts_total,
+ 'dur_ms', hsc_based_startup_times.ts_total / 1e6
)
FROM hsc_based_startup_times WHERE id = launches.id
)
diff --git a/src/trace_processor/metrics/android/hsc_startups.sql b/src/trace_processor/metrics/android/hsc_startups.sql
index 330aa63..7df0663 100644
--- a/src/trace_processor/metrics/android/hsc_startups.sql
+++ b/src/trace_processor/metrics/android/hsc_startups.sql
@@ -36,9 +36,9 @@
INNER JOIN process_track on slices.track_id = process_track.id
INNER JOIN thread USING(upid);
-CREATE TABLE hsc_based_startup_times(package STRING, id INT, dur_ns INT);
+CREATE TABLE hsc_based_startup_times(package STRING, id INT, ts_total INT);
--- Netflix
+-- Calculator
INSERT INTO hsc_based_startup_times
SELECT
launches.package as package,
@@ -46,7 +46,92 @@
frame_times.ts_end - launches.ts as ts_total
FROM frame_times
INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
-WHERE frame_times.ts < (SELECT ts FROM functions WHERE function_name LIKE "animator%" AND process_name LIKE "%lix.mediaclient" ORDER BY ts LIMIT 1)
+WHERE frame_times.frame_number=2 AND frame_times.name LIKE "%roid.calcul%";
+
+-- Calendar
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts_end > (SELECT ts + dur FROM functions WHERE function_name LIKE "animator:growScale" AND process_name LIKE "%id.calendar" ORDER BY ts DESC LIMIT 1) AND frame_times.name LIKE "%id.calendar%"
+ORDER BY ts_total LIMIT 1;
+
+-- Camera
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=1 AND frame_times.name LIKE "%id.GoogleCamera%";LECT ts + dur FROM functions WHERE function_name="ShutterButtonEnabled" AND process_name LIKE "%id.GoogleCamera%" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%id.GoogleCamera%"
+ORDER BY ts_total LIMIT 1;
+
+-- Chrome
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=1 AND frame_times.name LIKE "%chrome%";
+
+-- Clock
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts > (SELECT ts + dur FROM functions WHERE function_name="animator:translationZ" AND process_name LIKE "%id.deskclock" ORDER BY ts DESC LIMIT 1) AND frame_times.name LIKE "%id.deskclock"
+ORDER BY ts_total LIMIT 1;
+
+-- Contacts
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts > (SELECT ts + dur FROM functions WHERE function_name="animator:elevation" AND process_name LIKE "%id.contacts" ORDER BY ts DESC LIMIT 1) AND frame_times.name LIKE "%id.contacts"
+ORDER BY ts_total LIMIT 1;
+
+-- Dialer
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=2 AND frame_times.name LIKE "%id.dialer";
+
+-- Gmail
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts > (SELECT ts + dur FROM functions WHERE function_name="animator:elevation" AND process_name LIKE "%android.gm" ORDER BY ts DESC LIMIT 1) AND frame_times.name LIKE "%android.gm"
+ORDER BY ts_total LIMIT 1;
+
+-- Instagram
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts_end > (SELECT start_ts FROM process WHERE name LIKE "%mqtt%" ORDER BY start_ts LIMIT 1) AND frame_times.name LIKE "%stagram.android%"
ORDER BY ts_total LIMIT 1;
-- Maps
@@ -58,3 +143,76 @@
FROM frame_times
INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
WHERE frame_times.frame_number=1 AND frame_times.name LIKE "%maps%";
+
+-- Messages
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts_end > (SELECT ts + dur FROM functions WHERE function_name="animator:translationZ" AND process_name LIKE "%apps.messaging%" ORDER BY ts DESC LIMIT 1) AND frame_times.name LIKE "%apps.messaging%"
+ORDER BY ts_total LIMIT 1;
+
+-- Netflix
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts < (SELECT ts FROM functions WHERE function_name LIKE "animator%" AND process_name LIKE "%lix.mediaclient" ORDER BY ts LIMIT 1) AND frame_times.name LIKE "%lix.mediaclient%"
+ORDER BY ts_total DESC LIMIT 1;
+
+-- Photos
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=1 AND frame_times.name LIKE "%apps.photos%";
+
+-- Settings
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=4 AND frame_times.name LIKE "%settings%";
+
+-- Snapchat
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=1 AND frame_times.name LIKE "%napchat.android";
+
+-- Twitter
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.ts > (SELECT ts + dur FROM functions WHERE function_name="animator:translationZ" AND process_name LIKE "%tter.android" ORDER BY ts DESC LIMIT 1) AND frame_times.name LIKE "%tter.android"
+ORDER BY ts_total LIMIT 1;
+
+-- Youtube
+INSERT INTO hsc_based_startup_times
+SELECT
+ launches.package as package,
+ launches.id as id,
+ frame_times.ts_end - launches.ts as ts_total
+FROM frame_times
+INNER JOIN launches on launches.package LIKE '%' || frame_times.name || '%'
+WHERE frame_times.frame_number=1 AND frame_times.name LIKE "%id.youtube";