Merge "perfetto: fix descriptor naming to prevent double proto gen"
diff --git a/Android.bp b/Android.bp
index 5681e0a..8d92551 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8431,6 +8431,7 @@
         "src/trace_processor/dynamic/experimental_slice_layout_generator_unittest.cc",
         "src/trace_processor/dynamic/thread_state_generator_unittest.cc",
         "src/trace_processor/forwarding_trace_parser_unittest.cc",
+        "src/trace_processor/importers/ftrace/binder_tracker_unittest.cc",
         "src/trace_processor/importers/ftrace/sched_event_tracker_unittest.cc",
         "src/trace_processor/importers/fuchsia/fuchsia_trace_utils_unittest.cc",
         "src/trace_processor/importers/memory_tracker/graph_processor_unittest.cc",
diff --git a/CHANGELOG b/CHANGELOG
index 2a1bfbd..ebad664 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,7 +4,8 @@
   Trace Processor:
     *
   UI:
-    *
+    * Added flow arrows between binder transaction pairs (request/reply
+      and async send/async recv).
   SDK:
     *
 
diff --git a/protos/perfetto/metrics/android/network_metric.proto b/protos/perfetto/metrics/android/network_metric.proto
index fea1d1d..d06deab 100644
--- a/protos/perfetto/metrics/android/network_metric.proto
+++ b/protos/perfetto/metrics/android/network_metric.proto
@@ -53,10 +53,10 @@
   }
 
   message Tx {
-    // Total packets statistic
+    // Total packets statistic.
     optional PacketStatistic total = 1;
 
-    // Per core packets statistic
+    // Per core packets statistic.
     repeated CorePacketStatistic core = 2;
   }
 
@@ -110,4 +110,7 @@
 
   // SoftIrq NET_RX action metrics.
   optional NetRxAction net_rx_action = 2;
+
+  // Packet retransmission rate.
+  optional double retransmission_rate = 3;
 }
diff --git a/protos/perfetto/metrics/chrome/scroll_jank.proto b/protos/perfetto/metrics/chrome/scroll_jank.proto
index 6fea1d8..3fe397d 100644
--- a/protos/perfetto/metrics/chrome/scroll_jank.proto
+++ b/protos/perfetto/metrics/chrome/scroll_jank.proto
@@ -30,4 +30,5 @@
   optional int64 num_scroll_update_count = 5 [(unit) = "count_biggerIsBetter"];
   optional int64 num_scroll_update_jank_count = 6
       [(unit) = "count_smallerIsBetter"];
+  optional double scroll_jank_budget_ms = 7 [(unit) = "ms_smallerIsBetter"];
 }
diff --git a/protos/perfetto/metrics/chrome/touch_jank.proto b/protos/perfetto/metrics/chrome/touch_jank.proto
index beebfb5..20318b8 100644
--- a/protos/perfetto/metrics/chrome/touch_jank.proto
+++ b/protos/perfetto/metrics/chrome/touch_jank.proto
@@ -31,4 +31,5 @@
   optional int64 num_touch_update_count = 5 [(unit) = "count_biggerIsBetter"];
   optional int64 num_touch_update_jank_count = 6
       [(unit) = "count_smallerIsBetter"];
+  optional double touch_jank_budget_ms = 7 [(unit) = "ms_smallerIsBetter"];
 }
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 03f6690..ee8f5da 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -910,10 +910,10 @@
   }
 
   message Tx {
-    // Total packets statistic
+    // Total packets statistic.
     optional PacketStatistic total = 1;
 
-    // Per core packets statistic
+    // Per core packets statistic.
     repeated CorePacketStatistic core = 2;
   }
 
@@ -967,6 +967,9 @@
 
   // SoftIrq NET_RX action metrics.
   optional NetRxAction net_rx_action = 2;
+
+  // Packet retransmission rate.
+  optional double retransmission_rate = 3;
 }
 
 // End of protos/perfetto/metrics/android/network_metric.proto
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index a34bf3c..1cb0ec2 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/python/setup.py b/python/setup.py
index 3c1598e..19d30dd 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -2,10 +2,13 @@
 
 setup(
     name='perfetto',
-    packages=['perfetto', 'perfetto.trace_processor'],
+    packages=[
+        'perfetto', 'perfetto.batch_trace_processor',
+        'perfetto.trace_processor', 'perfetto.trace_uri_resolver'
+    ],
     package_data={'perfetto.trace_processor': ['*.descriptor']},
     include_package_data=True,
-    version='0.3.0',
+    version='0.4.0',
     license='apache-2.0',
     description='Python API for Perfetto\'s Trace Processor',
     author='Perfetto',
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 8d821bf..a6571fd 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -394,6 +394,7 @@
   testonly = true
   sources = [
     "forwarding_trace_parser_unittest.cc",
+    "importers/ftrace/binder_tracker_unittest.cc",
     "importers/ftrace/sched_event_tracker_unittest.cc",
     "importers/fuchsia/fuchsia_trace_utils_unittest.cc",
     "importers/memory_tracker/graph_processor_unittest.cc",
diff --git a/src/trace_processor/importers/ftrace/binder_tracker.cc b/src/trace_processor/importers/ftrace/binder_tracker.cc
index 64eee90..fd229f1 100644
--- a/src/trace_processor/importers/ftrace/binder_tracker.cc
+++ b/src/trace_processor/importers/ftrace/binder_tracker.cc
@@ -17,9 +17,11 @@
 #include "src/trace_processor/importers/ftrace/binder_tracker.h"
 #include "perfetto/base/compiler.h"
 #include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/importers/common/flow_tracker.h"
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
 namespace perfetto {
@@ -74,7 +76,6 @@
       flags_(context->storage->InternString("flags")),
       code_(context->storage->InternString("code")),
       calling_tid_(context->storage->InternString("calling tid")),
-      dest_slice_id_(context->storage->InternString("destination slice id")),
       data_size_(context->storage->InternString("data size")),
       offsets_size_(context->storage->InternString("offsets size")) {}
 
@@ -84,8 +85,8 @@
                                 uint32_t tid,
                                 int32_t transaction_id,
                                 int32_t dest_node,
-                                int32_t dest_tgid,
-                                int32_t dest_tid,
+                                uint32_t dest_tgid,
+                                uint32_t dest_tid,
                                 bool is_reply,
                                 uint32_t flags,
                                 StringId code) {
@@ -105,95 +106,95 @@
                                  base::StringView(flag_str))));
     inserter->AddArg(code_, Variadic::String(code));
     inserter->AddArg(calling_tid_, Variadic::UnsignedInteger(tid));
-    // TODO(hjd): The legacy UI included the calling pid in the args,
-    // is this necessary? It's complicated in our case because process
-    // association might not happen until after the binder transaction slices
-    // have been parsed. We would need to backfill the arg.
   };
 
-  if (is_reply) {
-    // Reply slices have accurate dest information, so we can add it.
-    const auto& thread_table = context_->storage->thread_table();
-    UniqueTid utid = context_->process_tracker->GetOrCreateThread(
-        static_cast<uint32_t>(dest_tid));
-    StringId dest_thread_name = thread_table.name()[utid];
-    auto dest_args_inserter = [this, dest_tid, &dest_thread_name](
-                                  ArgsTracker::BoundInserter* inserter) {
-      inserter->AddArg(dest_thread_, Variadic::Integer(dest_tid));
-      inserter->AddArg(dest_name_, Variadic::String(dest_thread_name));
-    };
-    context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_,
-                                     dest_args_inserter);
-    context_->slice_tracker->End(ts, track_id, kNullStringId, kNullStringId,
-                                 args_inserter);
-    awaiting_rcv_for_reply_.insert(transaction_id);
-    return;
-  }
+  bool is_oneway = (flags & kOneWay) == kOneWay;
+  auto insert_slice = [&]() {
+    if (is_reply) {
+      UniqueTid utid = context_->process_tracker->GetOrCreateThread(
+          static_cast<uint32_t>(dest_tid));
+      StringId dest_thread_name =
+          context_->storage->thread_table().name()[utid];
+      auto dest_args_inserter = [this, dest_tid, &dest_thread_name](
+                                    ArgsTracker::BoundInserter* inserter) {
+        inserter->AddArg(dest_thread_, Variadic::Integer(dest_tid));
+        inserter->AddArg(dest_name_, Variadic::String(dest_thread_name));
+      };
+      context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_,
+                                       dest_args_inserter);
+      return context_->slice_tracker->End(ts, track_id, kNullStringId,
+                                          kNullStringId, args_inserter);
+    }
+    if (is_oneway) {
+      return context_->slice_tracker->Scoped(ts, track_id, binder_category_id_,
+                                             transaction_async_id_, 0,
+                                             args_inserter);
+    }
+    return context_->slice_tracker->Begin(ts, track_id, binder_category_id_,
+                                          transaction_slice_id_, args_inserter);
+  };
 
-  bool expects_reply = !is_reply && ((flags & kOneWay) == 0);
-
-  if (expects_reply) {
-    context_->slice_tracker->Begin(ts, track_id, binder_category_id_,
-                                   transaction_slice_id_, args_inserter);
-    transaction_await_rcv[transaction_id] = track_id;
-  } else {
-    context_->slice_tracker->Scoped(ts, track_id, binder_category_id_,
-                                    transaction_async_id_, 0, args_inserter);
-    awaiting_async_rcv_[transaction_id] = args_inserter;
-  }
+  OutstandingTransaction transaction;
+  transaction.is_reply = is_reply;
+  transaction.is_oneway = is_oneway;
+  transaction.args_inserter = args_inserter;
+  transaction.send_track_id = track_id;
+  transaction.send_slice_id = insert_slice();
+  outstanding_transactions_.Insert(transaction_id, std::move(transaction));
 }
 
 void BinderTracker::TransactionReceived(int64_t ts,
                                         uint32_t pid,
                                         int32_t transaction_id) {
+  const OutstandingTransaction* opt_transaction =
+      outstanding_transactions_.Find(transaction_id);
+  if (!opt_transaction) {
+    // If we don't know what type of transaction it is, we don't know how to
+    // insert the slice.
+    // TODO(lalitm): maybe we should insert a dummy slice anyway - seems like
+    // a questionable idea to just ignore these completely.
+    return;
+  }
+
+  OutstandingTransaction transaction(std::move(*opt_transaction));
+  outstanding_transactions_.Erase(transaction_id);
+
   UniqueTid utid = context_->process_tracker->GetOrCreateThread(pid);
-  const auto& thread_table = context_->storage->thread_table();
-  StringId thread_name = thread_table.name()[utid];
   TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
-  if (awaiting_rcv_for_reply_.count(transaction_id) > 0) {
+
+  if (transaction.is_reply) {
+    // Simply end the slice started back when the first |expects_reply|
+    // transaction was sent.
     context_->slice_tracker->End(ts, track_id);
-    awaiting_rcv_for_reply_.erase(transaction_id);
     return;
   }
 
-  TrackId* rcv_track_id = transaction_await_rcv.Find(transaction_id);
-  if (rcv_track_id) {
-    // First begin the reply slice to get its slice id.
-    auto reply_slice_id = context_->slice_tracker->Begin(
+  base::Optional<SliceId> recv_slice_id;
+  if (transaction.is_oneway) {
+    recv_slice_id = context_->slice_tracker->Scoped(
+        ts, track_id, binder_category_id_, async_rcv_id_, 0,
+        std::move(transaction.args_inserter));
+  } else {
+    if (transaction.send_track_id) {
+      auto args_inserter = [this, utid,
+                            pid](ArgsTracker::BoundInserter* inserter) {
+        inserter->AddArg(dest_thread_, Variadic::UnsignedInteger(pid));
+        inserter->AddArg(
+            dest_name_,
+            Variadic::String(context_->storage->thread_table().name()[utid]));
+      };
+      context_->slice_tracker->AddArgs(*transaction.send_track_id,
+                                       binder_category_id_,
+                                       transaction_slice_id_, args_inserter);
+    }
+    recv_slice_id = context_->slice_tracker->Begin(
         ts, track_id, binder_category_id_, reply_id_);
-    // Add accurate dest info to the binder transaction slice.
-    auto args_inserter = [this, pid, &thread_name, &reply_slice_id](
-                             ArgsTracker::BoundInserter* inserter) {
-      inserter->AddArg(dest_thread_, Variadic::UnsignedInteger(pid));
-      inserter->AddArg(dest_name_, Variadic::String(thread_name));
-      if (reply_slice_id.has_value())
-        inserter->AddArg(dest_slice_id_,
-                         Variadic::UnsignedInteger(reply_slice_id->value));
-    };
-    // Add the dest args to the current transaction slice and get the slice id.
-    auto transaction_slice_id =
-        context_->slice_tracker->AddArgs(*rcv_track_id, binder_category_id_,
-                                         transaction_slice_id_, args_inserter);
-
-    // Add the dest slice id to the reply slice that has just begun.
-    auto reply_dest_inserter =
-        [this, &transaction_slice_id](ArgsTracker::BoundInserter* inserter) {
-          if (transaction_slice_id.has_value())
-            inserter->AddArg(dest_slice_id_, Variadic::UnsignedInteger(
-                                                 transaction_slice_id.value()));
-        };
-    context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_,
-                                     reply_dest_inserter);
-    transaction_await_rcv.Erase(transaction_id);
-    return;
   }
 
-  SetArgsCallback* args = awaiting_async_rcv_.Find(transaction_id);
-  if (args) {
-    context_->slice_tracker->Scoped(ts, track_id, binder_category_id_,
-                                    async_rcv_id_, 0, *args);
-    awaiting_async_rcv_.Erase(transaction_id);
-    return;
+  // Create a flow between the sending slice and this slice.
+  if (transaction.send_slice_id && recv_slice_id) {
+    context_->flow_tracker->InsertFlow(*transaction.send_slice_id,
+                                       *recv_slice_id);
   }
 }
 
diff --git a/src/trace_processor/importers/ftrace/binder_tracker.h b/src/trace_processor/importers/ftrace/binder_tracker.h
index a9482de..aa710e3 100644
--- a/src/trace_processor/importers/ftrace/binder_tracker.h
+++ b/src/trace_processor/importers/ftrace/binder_tracker.h
@@ -21,6 +21,7 @@
 
 #include "perfetto/base/flat_set.h"
 #include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/optional.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/destructible.h"
@@ -50,8 +51,8 @@
                    uint32_t tid,
                    int32_t transaction_id,
                    int32_t dest_node,
-                   int32_t dest_tgid,
-                   int32_t dest_tid,
+                   uint32_t dest_tgid,
+                   uint32_t dest_tid,
                    bool is_reply,
                    uint32_t flags,
                    StringId code);
@@ -67,14 +68,19 @@
                            uint64_t offsets_size);
 
  private:
-  TraceProcessorContext* const context_;
-  base::FlatSet<int32_t> awaiting_rcv_for_reply_;
+  struct OutstandingTransaction {
+    bool is_reply = false;
+    bool is_oneway = false;
+    SetArgsCallback args_inserter;
+    base::Optional<TrackId> send_track_id;
+    base::Optional<SliceId> send_slice_id;
+  };
 
-  base::FlatHashMap<int32_t, TrackId> transaction_await_rcv;
-  base::FlatHashMap<int32_t, SetArgsCallback> awaiting_async_rcv_;
+  TraceProcessorContext* const context_;
+
+  base::FlatHashMap<int32_t, OutstandingTransaction> outstanding_transactions_;
 
   base::FlatHashMap<uint32_t, int64_t> attempt_lock_;
-
   base::FlatHashMap<uint32_t, int64_t> lock_acquired_;
 
   const StringId binder_category_id_;
@@ -93,7 +99,6 @@
   const StringId flags_;
   const StringId code_;
   const StringId calling_tid_;
-  const StringId dest_slice_id_;
   const StringId data_size_;
   const StringId offsets_size_;
 };
diff --git a/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc b/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc
new file mode 100644
index 0000000..7f62c06
--- /dev/null
+++ b/src/trace_processor/importers/ftrace/binder_tracker_unittest.cc
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#include "src/trace_processor/importers/ftrace/binder_tracker.h"
+
+#include "perfetto/base/logging.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+constexpr int kOneWay = 0x01;
+
+class BinderTrackerTest : public ::testing::Test {
+ public:
+  BinderTrackerTest() {
+    context.storage.reset(new TraceStorage());
+    context.global_args_tracker.reset(new GlobalArgsTracker(&context));
+    context.args_tracker.reset(new ArgsTracker(&context));
+    context.slice_tracker.reset(new SliceTracker(&context));
+    context.process_tracker.reset(new ProcessTracker(&context));
+    context.track_tracker.reset(new TrackTracker(&context));
+    context.flow_tracker.reset(new FlowTracker(&context));
+    binder_tracker = BinderTracker::GetOrCreate(&context);
+  }
+
+ protected:
+  TraceProcessorContext context;
+  BinderTracker* binder_tracker;
+};
+
+TEST_F(BinderTrackerTest, RequestReply) {
+  int64_t req_ts = 100;
+  int64_t req_recv_ts = 105;
+  int64_t rep_ts = 150;
+  int64_t rep_recv_ts = 155;
+
+  uint32_t req_tid = 5;
+  uint32_t rep_tid = 10;
+
+  int32_t req_transaction_id = 1234;
+  int32_t rep_transaction_id = 5678;
+
+  binder_tracker->Transaction(req_ts, req_tid, req_transaction_id, 9, rep_tid,
+                              rep_tid, false, 0, kNullStringId);
+  binder_tracker->TransactionReceived(req_recv_ts, rep_tid, req_transaction_id);
+
+  binder_tracker->Transaction(rep_ts, rep_tid, rep_transaction_id, 99, req_tid,
+                              req_tid, true, 0, kNullStringId);
+  binder_tracker->TransactionReceived(rep_recv_ts, req_tid, rep_transaction_id);
+
+  const auto& thread = context.storage->thread_table();
+  const auto& track = context.storage->thread_track_table();
+  const auto& slice = context.storage->slice_table();
+  const auto& flow = context.storage->flow_table();
+  ASSERT_EQ(slice.row_count(), 2u);
+
+  auto tid_for_slice = [&](uint32_t row) {
+    TrackId track_id = slice.track_id()[row];
+    UniqueTid utid = track.utid()[*track.id().IndexOf(track_id)];
+    return thread.tid()[utid];
+  };
+
+  ASSERT_EQ(slice.ts()[0], req_ts);
+  ASSERT_EQ(slice.dur()[0], rep_recv_ts - req_ts);
+  ASSERT_EQ(tid_for_slice(0), req_tid);
+
+  ASSERT_EQ(slice.ts()[1], req_recv_ts);
+  ASSERT_EQ(slice.dur()[1], rep_ts - req_recv_ts);
+  ASSERT_EQ(tid_for_slice(1), rep_tid);
+
+  ASSERT_EQ(flow.row_count(), 1u);
+  ASSERT_EQ(flow.slice_out()[0], slice.id()[0]);
+  ASSERT_EQ(flow.slice_in()[0], slice.id()[1]);
+}
+
+TEST_F(BinderTrackerTest, Oneway) {
+  int64_t sen_ts = 100;
+  int64_t rec_ts = 150;
+
+  uint32_t sen_tid = 5;
+  uint32_t rec_tid = 10;
+
+  int32_t transaction_id = 1234;
+
+  binder_tracker->Transaction(sen_ts, sen_tid, transaction_id, 9, rec_tid,
+                              rec_tid, false, kOneWay, kNullStringId);
+  binder_tracker->TransactionReceived(rec_ts, rec_tid, transaction_id);
+
+  const auto& thread = context.storage->thread_table();
+  const auto& track = context.storage->thread_track_table();
+  const auto& slice = context.storage->slice_table();
+  const auto& flow = context.storage->flow_table();
+  ASSERT_EQ(slice.row_count(), 2u);
+
+  auto tid_for_slice = [&](uint32_t row) {
+    TrackId track_id = slice.track_id()[row];
+    UniqueTid utid = track.utid()[*track.id().IndexOf(track_id)];
+    return thread.tid()[utid];
+  };
+
+  ASSERT_EQ(slice.ts()[0], sen_ts);
+  ASSERT_EQ(slice.dur()[0], 0);
+  ASSERT_EQ(tid_for_slice(0), sen_tid);
+
+  ASSERT_EQ(slice.ts()[1], rec_ts);
+  ASSERT_EQ(slice.dur()[1], 0);
+  ASSERT_EQ(tid_for_slice(1), rec_tid);
+
+  ASSERT_EQ(flow.row_count(), 1u);
+  ASSERT_EQ(flow.slice_out()[0], slice.id()[0]);
+  ASSERT_EQ(flow.slice_in()[0], slice.id()[1]);
+}
+
+}  // namespace
+}  // namespace trace_processor
+}  // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 478feb8..9d5e382 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -1289,8 +1289,8 @@
   protos::pbzero::BinderTransactionFtraceEvent::Decoder evt(blob.data,
                                                             blob.size);
   int32_t dest_node = static_cast<int32_t>(evt.target_node());
-  int32_t dest_tgid = static_cast<int32_t>(evt.to_proc());
-  int32_t dest_tid = static_cast<int32_t>(evt.to_thread());
+  uint32_t dest_tgid = static_cast<uint32_t>(evt.to_proc());
+  uint32_t dest_tid = static_cast<uint32_t>(evt.to_thread());
   int32_t transaction_id = static_cast<int32_t>(evt.debug_id());
   bool is_reply = static_cast<int32_t>(evt.reply()) == 1;
   uint32_t flags = static_cast<uint32_t>(evt.flags());
diff --git a/src/trace_processor/importers/systrace/systrace_line_parser.cc b/src/trace_processor/importers/systrace/systrace_line_parser.cc
index 16b6eb8..4cfd788 100644
--- a/src/trace_processor/importers/systrace/systrace_line_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_line_parser.cc
@@ -153,8 +153,8 @@
   } else if (line.event_name == "binder_transaction") {
     auto id = base::StringToInt32(args["transaction"]);
     auto dest_node = base::StringToInt32(args["dest_node"]);
-    auto dest_tgid = base::StringToInt32(args["dest_proc"]);
-    auto dest_tid = base::StringToInt32(args["dest_thread"]);
+    auto dest_tgid = base::StringToUInt32(args["dest_proc"]);
+    auto dest_tid = base::StringToUInt32(args["dest_thread"]);
     auto is_reply = base::StringToInt32(args["reply"]).value() == 1;
     auto flags_str = args["flags"];
     char* end;
diff --git a/src/trace_processor/metrics/sql/android/android_netperf.sql b/src/trace_processor/metrics/sql/android/android_netperf.sql
index 8a67a7d..c7c0b65 100644
--- a/src/trace_processor/metrics/sql/android/android_netperf.sql
+++ b/src/trace_processor/metrics/sql/android/android_netperf.sql
@@ -47,6 +47,16 @@
  SELECT DISTINCT dev
  FROM rx_packets;
 
+DROP VIEW IF EXISTS tcp_retransmitted_count;
+CREATE VIEW tcp_retransmitted_count AS
+  SELECT
+     COUNT(1) AS cnt
+  FROM slice s
+  LEFT JOIN track t
+    ON s.track_id = t.id
+  WHERE
+    t.name = "TCP Retransmit Skb";
+
 DROP VIEW IF EXISTS device_per_core_ingress_traffic;
 CREATE VIEW device_per_core_ingress_traffic AS
   SELECT
@@ -241,6 +251,11 @@
            runtime/total_packet/1e6
          FROM total_net_rx_action_statistic
        )
+    ),
+    'retransmission_rate', (
+      SELECT
+        (SELECT cnt FROM tcp_retransmitted_count) * 100.0 / COUNT(1)
+      FROM tx_packets
     )
   );
 
diff --git a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
index cfbc96b..6e7ea1a 100644
--- a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
+++ b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
@@ -221,7 +221,7 @@
 -- rate more than 1 FPS (and therefore VSync interval less than a second), this
 -- ratio should increase with increments more than minimal value in numerator
 -- (1ns) divided by maximum value in denominator, giving 1e-9.
--- Note: Logic is inside the isJankyFrame function found in jank_utilities.sql.
+-- Note: Logic is inside the IsJankyFrame function found in jank_utilities.sql.
 DROP VIEW IF EXISTS {{prefix}}_jank_maybe_null_prev_and_next;
 CREATE VIEW {{prefix}}_jank_maybe_null_prev_and_next AS
   SELECT
@@ -237,6 +237,15 @@
 
 -- This just uses prev_jank and next_jank to see if each "update" event is a
 -- jank.
+--
+-- JankBudget is the time in ns that we need to reduce the current
+-- gesture (|id|) for this frame not to be considered janky (i.e., how much
+-- faster for IsJankyFrame() to have not returned true).
+--
+-- For JankBudget we use the frames_exact of current, previous and next to find
+-- the jank budget in exact frame count. We then multiply by avg_vsync_internal
+-- to get the jank budget time.
+-- Note: Logic is inside the JankBudget function found in jank_utilities.sql.
 DROP VIEW IF EXISTS {{prefix}}_jank;
 CREATE VIEW {{prefix}}_jank AS
   SELECT
@@ -244,6 +253,8 @@
     (next_jank IS NOT NULL AND next_jank) OR
     (prev_jank IS NOT NULL AND prev_jank)
     AS jank,
+    JankBudget(gesture_frames_exact, prev_gesture_frames_exact,
+      next_gesture_frames_exact) * avg_vsync_interval AS jank_budget,
     *
   FROM {{prefix}}_jank_maybe_null_prev_and_next
   ORDER BY {{id_field}} ASC, ts ASC;
@@ -274,6 +285,9 @@
         SELECT CAST(SUM(dur)/1e6 AS REAL) FROM {{prefix}}_jank WHERE jank
       ),
       'num_{{prefix}}_update_count', COUNT(*),
-      'num_{{prefix}}_update_jank_count', SUM(jank)
+      'num_{{prefix}}_update_jank_count', SUM(jank),
+      '{{prefix}}_jank_budget_ms', (
+        SELECT CAST(SUM(jank_budget) AS REAL) FROM {{prefix}}_jank WHERE jank
+      )
     )
   FROM {{prefix}}_jank;
diff --git a/src/trace_processor/metrics/sql/chrome/jank_utilities.sql b/src/trace_processor/metrics/sql/chrome/jank_utilities.sql
index 494b88c..44edb42 100644
--- a/src/trace_processor/metrics/sql/chrome/jank_utilities.sql
+++ b/src/trace_processor/metrics/sql/chrome/jank_utilities.sql
@@ -44,3 +44,40 @@
         $cur_frame_exact > $neighbour_frame_exact + 0.5 + 1e-9
     END'
 );
+
+SELECT CREATE_FUNCTION(
+  -- Function : function takes the cur_frame_exact, prev_frame_exact and
+  -- next_frame_exact and returns the value of the jank budget of the current
+  -- frame.
+  --
+  -- JankBudget is the minimum amount of frames/time we need to reduce the frame
+  -- duration by for it to be no longer considered janky.
+  'JankBudget(cur_frame_exact FLOAT, prev_frame_exact FLOAT, ' ||
+  ' next_frame_exact FLOAT)',
+  -- Returns the jank budget in percentage (i.e. 0.75) of vsync interval
+  -- percentage.
+  --
+  -- We determine the difference between the frame count of the current frame
+  -- and its consecutive frames by subtracting with the frame_exact values. We
+  -- null check for cases when the neighbor frame count can be null for the
+  -- first and last frames.
+  --
+  -- Since a frame is considered janky, if the difference in the frame count
+  -- with its adjacent frame is greater than 0.5 (half a vsync) which means we
+  -- need to reduce the frame count by a value less than 0.5 of maximum
+  -- difference in frame count for it to be no longer janky. We subtract 1e-9 as
+  -- we want to output minimum amount required.
+  'FLOAT',
+  'SELECT
+    COALESCE(
+      -- Could be null if next or previous is null.
+      MAX(
+        ($cur_frame_exact - $prev_frame_exact),
+        ($cur_frame_exact - $next_frame_exact)
+      ),
+      -- If one of them is null output the first non-null.
+      ($cur_frame_exact - $prev_frame_exact),
+      ($cur_frame_exact - $next_frame_exact)
+      -- Otherwise return null
+    ) - 0.5 - 1e-9'
+);
diff --git a/test/trace_processor/chrome/scroll_jank.out b/test/trace_processor/chrome/scroll_jank.out
index baaa642..163727e 100644
--- a/test/trace_processor/chrome/scroll_jank.out
+++ b/test/trace_processor/chrome/scroll_jank.out
@@ -1,141 +1,141 @@
 
-"gesture_scroll_id","trace_id","jank","ts","dur"
-2708,2709,0,544958000403,19009426
-2708,2711,0,544966000403,22609426
-2708,2715,0,544983000403,28089426
-2708,2717,0,544991000403,30714426
-2708,2719,0,544999000403,34740426
-2708,2721,0,545007000403,37462426
-2708,2725,0,545024000403,31889426
-2708,2727,0,545032000403,23876426
-2708,2729,0,545040000403,28316426
-2708,2733,0,545056000403,22620426
-2708,2735,0,545065000403,23642426
-2708,2739,0,545081000403,19016426
-2708,2741,0,545089000403,22491426
-2708,2743,0,545098000403,24940426
-2708,2747,0,545114000403,19365426
-2708,2749,0,545122000403,22629426
-2708,2753,0,545139000403,17669426
-2708,2755,0,545147000403,20941426
-2708,2757,0,545155000403,23321426
-2708,2761,0,545172000403,18585426
-2708,2763,0,545180000403,22430426
-2708,2765,0,545188000403,23545426
-2708,2769,0,545204000403,19115426
-2708,2771,0,545213000403,21107426
-2708,2773,0,545221000403,25065426
-2708,2777,0,545237000403,20064426
-2708,2779,0,545246000403,22190426
-2708,2783,0,545262000403,16635426
-2708,2785,0,545270000403,19926426
-2708,2787,0,545278000403,23003426
-2708,2791,0,545295000403,17169426
-2708,2793,0,545303000403,20626426
-2708,2795,0,545311000403,23560426
-2708,2799,0,545328000403,18191426
-2708,2801,0,545336000403,20911426
-2708,2803,0,545344000403,24228426
-2708,2807,0,545361000403,18189426
-2708,2809,0,545369000403,21379426
-2708,2811,0,545377000403,24913426
-2708,2815,0,545394000403,18671426
-2708,2817,0,545402000403,21928426
-2708,2821,0,545418000403,17254426
-2708,2823,0,545426000403,20407426
-2708,2825,0,545435000403,22633426
-2708,2827,0,545443000403,27179426
-2708,2831,0,545459000403,20575426
-2708,2833,0,545468000403,23489426
-2708,2837,0,545484000403,18277426
-2708,2839,0,545492000403,21649426
-2708,2841,0,545500000403,24734426
-2708,2845,0,545517000403,18824426
-2708,2847,0,545525000403,22343426
-2708,2849,0,545533000403,25222426
-2708,2853,0,545550000403,19151426
-2708,2855,0,545558000403,22660426
-2708,2859,0,545574000403,17603426
-2708,2861,0,545583000403,19608426
-2708,2863,0,545591000403,22822426
-2708,2867,0,545607000403,18005426
-2708,2869,0,545615000403,21063426
-2708,2871,0,545624000403,23894426
-2708,2875,0,545640000403,18611426
-2708,2877,0,545648000403,21759426
-2708,2879,0,545656000403,25004426
-2708,2881,0,545671000403,32742426
-2708,2884,0,545681794403,32652426
-2708,2885,0,545691182403,34488426
-2708,2886,0,545702355403,34887426
-2708,2887,0,545713526403,34615426
-2708,2888,0,545724697403,36799426
-2708,2889,0,545735867403,35326426
-2708,2890,0,545747040403,35047426
-2708,2891,0,545758211403,34990426
-2708,2892,0,545769381403,39529426
-2708,2893,0,545780550403,35967426
-2708,2894,1,545791721403,45468426
-2708,2895,1,545802892403,45651426
-2708,2897,0,545825234403,34662426
-2917,2918,0,546027000403,24672426
-2917,2920,0,546035000403,27274426
-2917,2922,0,546044000403,28587426
-2917,2924,1,546052000403,41821426
-2917,2926,1,546060000403,44914426
-2917,2930,0,546076000403,28902426
-2917,2932,0,546085000403,31881426
-2917,2934,0,546093000403,34989426
-2917,2938,1,546109000403,41953426
-2917,2940,0,546118000403,32872426
-2917,2942,0,546126000403,35348426
-2917,2946,0,546142000403,42106426
-2917,2948,1,546150000403,45005426
-2917,2950,0,546159000403,35994426
-2917,2954,0,546175000403,30970426
-2917,2956,1,546183000403,45256426
-2917,2960,0,546200000403,40097426
-2917,2962,0,546208000403,32086426
-2917,2964,0,546216000403,34686426
-2917,2968,0,546233000403,28852426
-2917,2970,0,546241000403,32494426
-2917,2972,0,546249000403,37304426
-2917,2976,0,546265000403,32101426
-2917,2978,0,546273000403,34156426
-2917,2982,0,546290000403,27915426
-2917,2984,0,546298000403,30723426
-2917,2986,0,546307000403,32918426
-2917,2990,0,546323000403,29800426
-2917,2992,0,546331000403,31314426
-2917,2994,0,546339000403,35092426
-2917,2998,0,546356000403,28702426
-2917,3000,0,546364000403,32457426
-2917,3002,0,546372000403,35043426
-2917,3006,0,546389000403,29285426
-2917,3008,0,546397000403,32831426
-2917,3010,0,546405000403,35630426
-2917,3014,0,546422000403,30119426
-2917,3016,0,546430000403,33185426
-2917,3020,0,546446000403,28386426
-2917,3022,0,546455000403,30102426
-2917,3024,0,546463000403,33512426
-2917,3028,0,546479000403,28455426
-2917,3030,0,546488000403,30791426
-2917,3032,0,546496000403,34105426
-2917,3036,0,546512000403,29329426
-2917,3038,0,546520000403,32321426
-2917,3040,0,546529000403,34457426
-2917,3044,0,546545000403,29668426
-2917,3046,0,546553000403,32830426
-2917,3048,0,546561000403,35849426
-2917,3052,0,546578000403,30365426
-2917,3054,0,546586000403,33666426
-2917,3056,0,546594000403,36913426
-2917,3060,0,546611000403,30855426
-2917,3062,0,546619000403,33897426
-2917,3064,0,546627000403,36941426
-2917,3068,0,546644000403,31194426
-2917,3070,0,546652000403,34276426
-2917,3074,0,546676000403,32746426
-2917,3077,0,546701627403,29680426
-2917,3079,0,546718977403,34597426
+"gesture_scroll_id","trace_id","jank","ts","dur","jank_budget"
+2708,2709,0,544958000403,19009426,-11933333.350000
+2708,2711,0,544966000403,22609426,-4733333.350000
+2708,2715,0,544983000403,28089426,-2853333.350000
+2708,2717,0,544991000403,30714426,-5708333.350000
+2708,2719,0,544999000403,34740426,-4307333.350000
+2708,2721,0,545007000403,37462426,-2760333.350000
+2708,2725,0,545024000403,31889426,-320333.350000
+2708,2727,0,545032000403,23876426,-12773333.350000
+2708,2729,0,545040000403,28316426,-2637333.350000
+2708,2733,0,545056000403,22620426,-9355333.350000
+2708,2735,0,545065000403,23642426,-3707333.350000
+2708,2739,0,545081000403,19016426,-11808333.350000
+2708,2741,0,545089000403,22491426,-4858333.350000
+2708,2743,0,545098000403,24940426,-2758333.350000
+2708,2747,0,545114000403,19365426,-11597333.350000
+2708,2749,0,545122000403,22629426,-3373333.350000
+2708,2753,0,545139000403,17669426,-11605333.350000
+2708,2755,0,545147000403,20941426,-5061333.350000
+2708,2757,0,545155000403,23321426,-3597333.350000
+2708,2761,0,545172000403,18585426,-12178333.350000
+2708,2763,0,545180000403,22430426,-4488333.350000
+2708,2765,0,545188000403,23545426,-3903333.350000
+2708,2769,0,545204000403,19115426,-10325333.350000
+2708,2771,0,545213000403,21107426,-6341333.350000
+2708,2773,0,545221000403,25065426,-3332333.350000
+2708,2777,0,545237000403,20064426,-10459333.350000
+2708,2779,0,545246000403,22190426,-2778333.350000
+2708,2783,0,545262000403,16635426,-11624333.350000
+2708,2785,0,545270000403,19926426,-5042333.350000
+2708,2787,0,545278000403,23003426,-2499333.350000
+2708,2791,0,545295000403,17169426,-11790333.350000
+2708,2793,0,545303000403,20626426,-4876333.350000
+2708,2795,0,545311000403,23560426,-2964333.350000
+2708,2799,0,545328000403,18191426,-11053333.350000
+2708,2801,0,545336000403,20911426,-5613333.350000
+2708,2803,0,545344000403,24228426,-2294333.350000
+2708,2807,0,545361000403,18189426,-11523333.350000
+2708,2809,0,545369000403,21379426,-5143333.350000
+2708,2811,0,545377000403,24913426,-2091333.350000
+2708,2815,0,545394000403,18671426,-11590333.350000
+2708,2817,0,545402000403,21928426,-3659333.350000
+2708,2821,0,545418000403,17254426,-11486333.350000
+2708,2823,0,545426000403,20407426,-5180333.350000
+2708,2825,0,545435000403,22633426,-6107333.350000
+2708,2827,0,545443000403,27179426,-1729333.350000
+2708,2831,0,545459000403,20575426,-11247333.350000
+2708,2833,0,545468000403,23489426,-3121333.350000
+2708,2837,0,545484000403,18277426,-11705333.350000
+2708,2839,0,545492000403,21649426,-4961333.350000
+2708,2841,0,545500000403,24734426,-2423333.350000
+2708,2845,0,545517000403,18824426,-11852333.350000
+2708,2847,0,545525000403,22343426,-4814333.350000
+2708,2849,0,545533000403,25222426,-2262333.350000
+2708,2853,0,545550000403,19151426,-11842333.350000
+2708,2855,0,545558000403,22660426,-3276333.350000
+2708,2859,0,545574000403,17603426,-10338333.350000
+2708,2861,0,545583000403,19608426,-6328333.350000
+2708,2863,0,545591000403,22822426,-3516333.350000
+2708,2867,0,545607000403,18005426,-11391333.350000
+2708,2869,0,545615000403,21063426,-5275333.350000
+2708,2871,0,545624000403,23894426,-3050333.350000
+2708,2875,0,545640000403,18611426,-11481333.350000
+2708,2877,0,545648000403,21759426,-5185333.350000
+2708,2879,0,545656000403,25004426,-5088333.350000
+2708,2881,0,545671000403,32742426,-595333.350000
+2708,2884,0,545681794403,32652426,-8423333.350000
+2708,2885,0,545691182403,34488426,-6497333.350000
+2708,2886,0,545702355403,34887426,-7934333.350000
+2708,2887,0,545713526403,34615426,-8605333.350000
+2708,2888,0,545724697403,36799426,-6149333.350000
+2708,2889,0,545735867403,35326426,-8054333.350000
+2708,2890,0,545747040403,35047426,-8276333.350000
+2708,2891,0,545758211403,34990426,-8390333.350000
+2708,2892,0,545769381403,39529426,-3794333.350000
+2708,2893,0,545780550403,35967426,-11895333.350000
+2708,2894,1,545791721403,45468426,1167666.650000
+2708,2895,1,545802892403,45651426,2655666.650000
+2708,2897,0,545825234403,34662426,1656666.650000
+2917,2918,0,546027000403,24672426,-10935333.350000
+2917,2920,0,546035000403,27274426,-5731333.350000
+2917,2922,0,546044000403,28587426,-7020333.350000
+2917,2924,1,546052000403,41821426,4900666.650000
+2917,2926,1,546060000403,44914426,7678666.650000
+2917,2930,0,546076000403,28902426,-11312333.350000
+2917,2932,0,546085000403,31881426,-5354333.350000
+2917,2934,0,546093000403,34989426,-5225333.350000
+2917,2938,1,546109000403,41953426,747666.650000
+2917,2940,0,546118000403,32872426,-10809333.350000
+2917,2942,0,546126000403,35348426,-5857333.350000
+2917,2946,0,546142000403,42106426,-1575333.350000
+2917,2948,1,546150000403,45005426,677666.650000
+2917,2950,0,546159000403,35994426,-3309333.350000
+2917,2954,0,546175000403,30970426,-13357333.350000
+2917,2956,1,546183000403,45256426,5952666.650000
+2917,2960,0,546200000403,40097426,-322333.350000
+2917,2962,0,546208000403,32086426,-10933333.350000
+2917,2964,0,546216000403,34686426,-2499333.350000
+2917,2968,0,546233000403,28852426,-11975333.350000
+2917,2970,0,546241000403,32494426,-4691333.350000
+2917,2972,0,546249000403,37304426,-3130333.350000
+2917,2976,0,546265000403,32101426,-10388333.350000
+2917,2978,0,546273000403,34156426,-2092333.350000
+2917,2982,0,546290000403,27915426,-11141333.350000
+2917,2984,0,546298000403,30723426,-5525333.350000
+2917,2986,0,546307000403,32918426,-5215333.350000
+2917,2990,0,546323000403,29800426,-9847333.350000
+2917,2992,0,546331000403,31314426,-6819333.350000
+2917,2994,0,546339000403,35092426,-1943333.350000
+2917,2998,0,546356000403,28702426,-12088333.350000
+2917,3000,0,546364000403,32457426,-4578333.350000
+2917,3002,0,546372000403,35043426,-2575333.350000
+2917,3006,0,546389000403,29285426,-11879333.350000
+2917,3008,0,546397000403,32831426,-4787333.350000
+2917,3010,0,546405000403,35630426,-2822333.350000
+2917,3014,0,546422000403,30119426,-11399333.350000
+2917,3016,0,546430000403,33185426,-3534333.350000
+2917,3020,0,546446000403,28386426,-10049333.350000
+2917,3022,0,546455000403,30102426,-6617333.350000
+2917,3024,0,546463000403,33512426,-3276333.350000
+2917,3028,0,546479000403,28455426,-10669333.350000
+2917,3030,0,546488000403,30791426,-5997333.350000
+2917,3032,0,546496000403,34105426,-3557333.350000
+2917,3036,0,546512000403,29329426,-11325333.350000
+2917,3038,0,546520000403,32321426,-5341333.350000
+2917,3040,0,546529000403,34457426,-3544333.350000
+2917,3044,0,546545000403,29668426,-11495333.350000
+2917,3046,0,546553000403,32830426,-5171333.350000
+2917,3048,0,546561000403,35849426,-2849333.350000
+2917,3052,0,546578000403,30365426,-11634333.350000
+2917,3054,0,546586000403,33666426,-5032333.350000
+2917,3056,0,546594000403,36913426,-2275333.350000
+2917,3060,0,546611000403,30855426,-11375333.350000
+2917,3062,0,546619000403,33897426,-5291333.350000
+2917,3064,0,546627000403,36941426,-2586333.350000
+2917,3068,0,546644000403,31194426,-11415333.350000
+2917,3070,0,546652000403,34276426,-5251333.350000
+2917,3074,0,546676000403,32746426,-5267333.350000
+2917,3077,0,546701627403,29680426,-11399333.350000
+2917,3079,0,546718977403,34597426,-3416333.350000
diff --git a/test/trace_processor/chrome/scroll_jank.sql b/test/trace_processor/chrome/scroll_jank.sql
index 2a502c1..9aaa99b 100644
--- a/test/trace_processor/chrome/scroll_jank.sql
+++ b/test/trace_processor/chrome/scroll_jank.sql
@@ -20,5 +20,6 @@
   trace_id,
   jank,
   ts,
-  dur
+  dur,
+  jank_budget
 FROM scroll_jank;
diff --git a/test/trace_processor/chrome/touch_jank.out b/test/trace_processor/chrome/touch_jank.out
index 9f55ea8..18edb3f 100644
--- a/test/trace_processor/chrome/touch_jank.out
+++ b/test/trace_processor/chrome/touch_jank.out
@@ -1,16 +1,16 @@
 
-"touch_id","trace_id","jank","ts","dur"
-6280,6288,1,1383122421558418,226350000
-6280,6312,0,1383122543558418,185244000
-6318,6328,1,1383123604558418,207945000
-6318,6414,0,1383124088558418,173233000
-6420,6552,0,1383125521558418,161901000
-6586,6602,0,1383126581558418,87964000
-6586,6693,1,1383127076558418,140115000
-6697,6698,1,1383127670558418,301236000
-6697,6723,0,1383127837558418,134236000
-6788,6802,0,1383129053558418,163272000
-6788,6877,1,1383129492558418,370407000
-6906,6911,1,1383130519558418,198057000
-6906,6915,0,1383130553558418,164057000
-6906,6940,0,1383130681558418,167758000
+"touch_id","trace_id","jank","ts","dur","jank_budget"
+6280,6288,1,1383122421558418,226350000,32772666.650000
+6280,6312,0,1383122543558418,185244000,-31034333.350000
+6318,6328,1,1383123604558418,207945000,26378666.650000
+6318,6414,0,1383124088558418,173233000,2998666.650000
+6420,6552,0,1383125521558418,161901000,65603666.650000
+6586,6602,0,1383126581558418,87964000,-60484333.350000
+6586,6693,1,1383127076558418,140115000,43817666.650000
+6697,6698,1,1383127670558418,301236000,158666666.650000
+6697,6723,0,1383127837558418,134236000,-37369333.350000
+6788,6802,0,1383129053558418,163272000,20702666.650000
+6788,6877,1,1383129492558418,370407000,198801666.650000
+6906,6911,1,1383130519558418,198057000,25666666.650000
+6906,6915,0,1383130553558418,164057000,-12034333.350000
+6906,6940,0,1383130681558418,167758000,-4632333.350000
diff --git a/test/trace_processor/chrome/touch_jank.sql b/test/trace_processor/chrome/touch_jank.sql
index 723b146..d601148 100644
--- a/test/trace_processor/chrome/touch_jank.sql
+++ b/test/trace_processor/chrome/touch_jank.sql
@@ -20,5 +20,6 @@
   trace_id,
   jank,
   ts,
-  dur
+  dur,
+  jank_budget
 FROM touch_jank;
diff --git a/test/trace_processor/chrome/touch_jank_synth.out b/test/trace_processor/chrome/touch_jank_synth.out
index 0c6f96f..44758af 100644
--- a/test/trace_processor/chrome/touch_jank_synth.out
+++ b/test/trace_processor/chrome/touch_jank_synth.out
@@ -1,5 +1,5 @@
 
-"touch_id","trace_id","jank","ts","dur"
-87654,34577,0,0,10000000
-87654,34578,1,16000000,33000000
-87654,34579,0,55000000,33000000
+"touch_id","trace_id","jank","ts","dur","jank_budget"
+87654,34577,0,0,10000000,-31333333.350000
+87654,34578,1,16000000,33000000,14666666.650000
+87654,34579,0,55000000,33000000,-8333333.350000
diff --git a/test/trace_processor/network/netperf_metric.out b/test/trace_processor/network/netperf_metric.out
index 24c8aac..c8afae8 100644
--- a/test/trace_processor/network/netperf_metric.out
+++ b/test/trace_processor/network/netperf_metric.out
@@ -141,4 +141,5 @@
     }
     avg_interstack_latency_ms: 0.4
   }
+  retransmission_rate: 20.0
 }
diff --git a/test/trace_processor/network/netperf_metric.textproto b/test/trace_processor/network/netperf_metric.textproto
index 1684df9..89513b6 100644
--- a/test/trace_processor/network/netperf_metric.textproto
+++ b/test/trace_processor/network/netperf_metric.textproto
@@ -25,6 +25,18 @@
       }
     }
     event {
+      timestamp: 100090000
+      pid: 234
+      tcp_retransmit_skb {
+        daddr: 19216801
+        saddr: 127001
+        dport: 5001
+        sport: 56789
+        state: 1
+        skaddr: 77889900
+      }
+    }
+    event {
       timestamp: 100100000
       pid: 200
       net_dev_xmit {