Merge "Update OWNERS to reflect active maintainers"
diff --git a/Android.bp b/Android.bp
index c7f2447..31e3604 100644
--- a/Android.bp
+++ b/Android.bp
@@ -744,6 +744,8 @@
     shared_libs: [
         "liblog",
     ],
+    host_supported: true,
+    vendor_available: true,
     export_include_dirs: [
         "include",
         "include/perfetto/base/build_configs/android_tree",
@@ -1907,7 +1909,6 @@
         "-DGOOGLE_PROTOBUF_NO_RTTI",
         "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
         "-DHAVE_HIDDEN",
-        "-fno-finite-loops",
     ],
     header_libs: [
         "bionic_libc_platform_headers",
@@ -3683,6 +3684,7 @@
         "protos/perfetto/metrics/android/mem_metric.proto",
         "protos/perfetto/metrics/android/mem_unagg_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
+        "protos/perfetto/metrics/android/network_metric.proto",
         "protos/perfetto/metrics/android/package_list.proto",
         "protos/perfetto/metrics/android/powrails_metric.proto",
         "protos/perfetto/metrics/android/process_metadata.proto",
@@ -3740,6 +3742,7 @@
         "protos/perfetto/metrics/android/mem_metric.proto",
         "protos/perfetto/metrics/android/mem_unagg_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
+        "protos/perfetto/metrics/android/network_metric.proto",
         "protos/perfetto/metrics/android/package_list.proto",
         "protos/perfetto/metrics/android/powrails_metric.proto",
         "protos/perfetto/metrics/android/process_metadata.proto",
@@ -8082,6 +8085,7 @@
         "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
+        "src/trace_processor/metrics/sql/android/android_netperf.sql",
         "src/trace_processor/metrics/sql/android/android_package_list.sql",
         "src/trace_processor/metrics/sql/android/android_powrails.sql",
         "src/trace_processor/metrics/sql/android/android_proxy_power.sql",
@@ -8141,6 +8145,7 @@
         "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql",
         "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql",
         "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql",
+        "src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql",
         "src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql",
         "src/trace_processor/metrics/sql/chrome/touch_flow_event.sql",
         "src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql",
diff --git a/BUILD b/BUILD
index ccc51d8..31ba472 100644
--- a/BUILD
+++ b/BUILD
@@ -1054,6 +1054,7 @@
         "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
+        "src/trace_processor/metrics/sql/android/android_netperf.sql",
         "src/trace_processor/metrics/sql/android/android_package_list.sql",
         "src/trace_processor/metrics/sql/android/android_powrails.sql",
         "src/trace_processor/metrics/sql/android/android_proxy_power.sql",
@@ -1113,6 +1114,7 @@
         "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_blocking_touch_move.sql",
         "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_get_bitmap.sql",
         "src/trace_processor/metrics/sql/chrome/scroll_jank_cause_queuing_delay.sql",
+        "src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql",
         "src/trace_processor/metrics/sql/chrome/test_chrome_metric.sql",
         "src/trace_processor/metrics/sql/chrome/touch_flow_event.sql",
         "src/trace_processor/metrics/sql/chrome/touch_flow_event_queuing_delay.sql",
@@ -2618,6 +2620,7 @@
         "protos/perfetto/metrics/android/mem_metric.proto",
         "protos/perfetto/metrics/android/mem_unagg_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
+        "protos/perfetto/metrics/android/network_metric.proto",
         "protos/perfetto/metrics/android/package_list.proto",
         "protos/perfetto/metrics/android/powrails_metric.proto",
         "protos/perfetto/metrics/android/process_metadata.proto",
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 9c87072..27b4e88 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -242,8 +242,7 @@
     if f.LocalPath() != 'tools/ftrace_proto_gen/event_list':
       continue
     if any((not new_line.startswith('removed')) and new_line != old_line
-           for old_line, new_line in itertools.izip(f.OldContents(),
-                                                    f.NewContents())):
+           for old_line, new_line in zip(f.OldContents(), f.NewContents())):
       return [
           output_api.PresubmitError(
               'event_list only has two supported changes: '
diff --git a/docs/instrumentation/tracing-sdk.md b/docs/instrumentation/tracing-sdk.md
index 4fe6893..252e637 100644
--- a/docs/instrumentation/tracing-sdk.md
+++ b/docs/instrumentation/tracing-sdk.md
@@ -30,7 +30,7 @@
 To start using the Client API, first check out the latest SDK release:
 
 ```bash
-git clone https://android.googlesource.com/platform/external/perfetto -b v21.0
+git clone https://android.googlesource.com/platform/external/perfetto -b v22.1
 ```
 
 The SDK consists of two files, `sdk/perfetto.h` and `sdk/perfetto.cc`. These are
diff --git a/examples/sdk/README.md b/examples/sdk/README.md
index a6ff1bf..8c56873 100644
--- a/examples/sdk/README.md
+++ b/examples/sdk/README.md
@@ -15,7 +15,7 @@
 First, check out the latest Perfetto release:
 
 ```bash
-git clone https://android.googlesource.com/platform/external/perfetto -b v21.0
+git clone https://android.googlesource.com/platform/external/perfetto -b v22.1
 ```
 
 Then, build using CMake:
diff --git a/include/perfetto/ext/base/scoped_file.h b/include/perfetto/ext/base/scoped_file.h
index 5a99de6..53d21b1 100644
--- a/include/perfetto/ext/base/scoped_file.h
+++ b/include/perfetto/ext/base/scoped_file.h
@@ -51,7 +51,7 @@
           T InvalidValue,
           bool CheckClose = true,
           class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
-class PERFETTO_EXPORT ScopedResource {
+class ScopedResource {
  public:
   using ValidityChecker = Checker;
   static constexpr T kInvalid = InvalidValue;
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index c217438..b4cc80b 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -40,6 +40,7 @@
     "mem_metric.proto",
     "mem_unagg_metric.proto",
     "multiuser_metric.proto",
+    "network_metric.proto",
     "package_list.proto",
     "powrails_metric.proto",
     "process_metadata.proto",
diff --git a/protos/perfetto/metrics/android/network_metric.proto b/protos/perfetto/metrics/android/network_metric.proto
new file mode 100644
index 0000000..61fac5c
--- /dev/null
+++ b/protos/perfetto/metrics/android/network_metric.proto
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message AndroidNetworkMetric {
+  message PacketStatistic {
+    // Packet count
+    optional int64 packets = 1;
+
+    // Packet Bytes
+    optional int64 bytes = 2;
+
+    // Timestamp when first packet received or transmitted
+    optional int64 first_packet_timestamp_ns = 3;
+
+    // Timestamp when last packet received or transmitted
+    optional int64 last_packet_timestamp_ns = 4;
+
+    // Interval between first & last packet. The minimum interval is 10ms.
+    optional int64 interval_ns = 5;
+
+    // Data Speed
+    optional double data_rate_kbps = 6;
+  }
+
+  message CorePacketStatistic {
+    optional uint32 id = 1;
+    optional PacketStatistic packet_statistic = 2;
+  }
+
+  message Rx {
+    // Total packets statistic
+    optional PacketStatistic total = 1;
+    // Per core packets statistic
+    repeated CorePacketStatistic core = 2;
+  }
+
+  message NetDevice {
+    // Network device name
+    optional string name = 1;
+
+    // Ingress traffic statistic
+    optional Rx rx = 2;
+  }
+
+  // Network device metrics
+  repeated NetDevice net_devices = 1;
+}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index c948145..8bdc51e 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -38,6 +38,7 @@
 import "protos/perfetto/metrics/android/mem_metric.proto";
 import "protos/perfetto/metrics/android/mem_unagg_metric.proto";
 import "protos/perfetto/metrics/android/multiuser_metric.proto";
+import "protos/perfetto/metrics/android/network_metric.proto";
 import "protos/perfetto/metrics/android/package_list.proto";
 import "protos/perfetto/metrics/android/powrails_metric.proto";
 import "protos/perfetto/metrics/android/profiler_smaps.proto";
@@ -94,7 +95,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 40
+// Next id: 41
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -196,6 +197,9 @@
   // Metrics for dynamic voltage and frequency scaling.
   optional AndroidDvfsMetric android_dvfs = 39;
 
+  // Metrics for network performance.
+  optional AndroidNetworkMetric android_netperf = 40;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 15a8d87..9bd0298 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -796,6 +796,55 @@
 }
 // End of protos/perfetto/metrics/android/multiuser_metric.proto
 
+// Begin of protos/perfetto/metrics/android/network_metric.proto
+
+message AndroidNetworkMetric {
+  message PacketStatistic {
+    // Packet count
+    optional int64 packets = 1;
+
+    // Packet Bytes
+    optional int64 bytes = 2;
+
+    // Timestamp when first packet received or transmitted
+    optional int64 first_packet_timestamp_ns = 3;
+
+    // Timestamp when last packet received or transmitted
+    optional int64 last_packet_timestamp_ns = 4;
+
+    // Interval between first & last packet. The minimum interval is 10ms.
+    optional int64 interval_ns = 5;
+
+    // Data Speed
+    optional double data_rate_kbps = 6;
+  }
+
+  message CorePacketStatistic {
+    optional uint32 id = 1;
+    optional PacketStatistic packet_statistic = 2;
+  }
+
+  message Rx {
+    // Total packets statistic
+    optional PacketStatistic total = 1;
+    // Per core packets statistic
+    repeated CorePacketStatistic core = 2;
+  }
+
+  message NetDevice {
+    // Network device name
+    optional string name = 1;
+
+    // Ingress traffic statistic
+    optional Rx rx = 2;
+  }
+
+  // Network device metrics
+  repeated NetDevice net_devices = 1;
+}
+
+// End of protos/perfetto/metrics/android/network_metric.proto
+
 // Begin of protos/perfetto/metrics/android/package_list.proto
 
 message AndroidPackageList {
@@ -1272,7 +1321,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 40
+// Next id: 41
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -1374,6 +1423,9 @@
   // Metrics for dynamic voltage and frequency scaling.
   optional AndroidDvfsMetric android_dvfs = 39;
 
+  // Metrics for network performance.
+  optional AndroidNetworkMetric android_netperf = 40;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/src/android_internal/health_hal.cc b/src/android_internal/health_hal.cc
index 0d8ad05..194cb73 100644
--- a/src/android_internal/health_hal.cc
+++ b/src/android_internal/health_hal.cc
@@ -22,6 +22,7 @@
 namespace perfetto {
 namespace android_internal {
 
+using ::android::hardware::Return;
 using ::android::hardware::health::V2_0::IHealth;
 using ::android::hardware::health::V2_0::Result;
 
@@ -48,35 +49,37 @@
   // in the same thread.
   // See https://source.android.com/devices/architecture/hidl/threading .
 
-  Result res;
+  Return<void> ret;
+  Result res = Result::UNKNOWN;
   switch (counter) {
     case BatteryCounter::kUnspecified:
-      res = Result::NOT_FOUND;
       break;
 
     case BatteryCounter::kCharge:
-      g_svc->getChargeCounter([&res, value](Result hal_res, int32_t hal_value) {
-        res = hal_res;
-        *value = hal_value;
-      });
+      ret = g_svc->getChargeCounter(
+          [&res, value](Result hal_res, int32_t hal_value) {
+            res = hal_res;
+            *value = hal_value;
+          });
       break;
 
     case BatteryCounter::kCapacityPercent:
-      g_svc->getCapacity([&res, value](Result hal_res, int64_t hal_value) {
+      ret = g_svc->getCapacity([&res, value](Result hal_res, int32_t hal_value) {
         res = hal_res;
         *value = hal_value;
       });
       break;
 
     case BatteryCounter::kCurrent:
-      g_svc->getCurrentNow([&res, value](Result hal_res, int32_t hal_value) {
-        res = hal_res;
-        *value = hal_value;
-      });
+      ret =
+          g_svc->getCurrentNow([&res, value](Result hal_res, int32_t hal_value) {
+            res = hal_res;
+            *value = hal_value;
+          });
       break;
 
     case BatteryCounter::kCurrentAvg:
-      g_svc->getCurrentAverage(
+      ret = g_svc->getCurrentAverage(
           [&res, value](Result hal_res, int32_t hal_value) {
             res = hal_res;
             *value = hal_value;
@@ -84,10 +87,10 @@
       break;
   }  // switch(counter)
 
-  if (res == Result::CALLBACK_DIED)
+  if (ret.isDeadObject())
     g_svc.clear();
 
-  return res == Result::SUCCESS;
+  return ret.isOk() && res == Result::SUCCESS;
 }
 
 }  // namespace android_internal
diff --git a/src/base/file_utils.cc b/src/base/file_utils.cc
index 8f998dd..91a5fc4 100644
--- a/src/base/file_utils.cc
+++ b/src/base/file_utils.cc
@@ -238,7 +238,9 @@
       return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
     WIN32_FIND_DATAA ffd;
 
-    base::ScopedResource<HANDLE, FindClose, nullptr, false,
+    // Wrap FindClose to: (1) make the return unix-style; (2) deal w/ stdcall.
+    static auto find_close = [](HANDLE h) { return FindClose(h) ? 0 : -1; };
+    base::ScopedResource<HANDLE, find_close, nullptr, false,
                          base::PlatformHandleChecker>
         hFind(FindFirstFileA(glob_path.c_str(), &ffd));
     if (!hFind) {
diff --git a/src/profiling/memory/heapprofd_end_to_end_test.cc b/src/profiling/memory/heapprofd_end_to_end_test.cc
index 3db57ee..df08bd9 100644
--- a/src/profiling/memory/heapprofd_end_to_end_test.cc
+++ b/src/profiling/memory/heapprofd_end_to_end_test.cc
@@ -312,6 +312,9 @@
 
   // Wait around so we can verify it did't crash.
   for (;;) {
+    // Call sleep, otherwise an empty busy loop is undefined behavior:
+    // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+    sleep(1);
   }
 }
 
@@ -351,6 +354,9 @@
 
   // Wait around so we can verify it did't crash.
   for (;;) {
+    // Call sleep, otherwise an empty busy loop is undefined behavior:
+    // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+    sleep(1);
   }
 }
 
@@ -387,6 +393,9 @@
 
   // Wait around so we can verify it did't crash.
   for (;;) {
+    // Call sleep, otherwise an empty busy loop is undefined behavior:
+    // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+    sleep(1);
   }
 }
 
@@ -493,6 +502,9 @@
 
   // Wait around so we can verify it didn't crash.
   for (;;) {
+    // Call sleep, otherwise an empty busy loop is undefined behavior:
+    // http://en.cppreference.com/w/cpp/language/memory_model#Progress_guarantee
+    sleep(1);
   }
 }
 
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index f34377f..d1c298a 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -760,7 +760,11 @@
     auto cleaner_objs = objects_tbl.FilterToRowMap(
         {objects_tbl.type_id().eq(class_id.value),
          objects_tbl.upid().eq(seq.current_upid),
-         objects_tbl.graph_sample_ts().eq(seq.current_ts)});
+         objects_tbl.graph_sample_ts().eq(seq.current_ts),
+         // If a Cleaner is not reachable, its associated native memory must
+         // have been already freed. Skip it.
+         objects_tbl.reachable().ne_value(SqlValue::Long(0)),
+        });
     for (auto obj_it = cleaner_objs.IterateRows(); obj_it; obj_it.Next()) {
       base::Optional<tables::HeapGraphObjectTable::Id> referent_id =
           GetReferenceByFieldName(objects_tbl.id()[obj_it.row()],
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc b/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
index 63d2fe6..9eb39f5 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker_unittest.cc
@@ -155,6 +155,13 @@
     tracker.AddObject(kSeqId, kPid, kTimestamp, std::move(obj));
   }
 
+  {
+    HeapGraphTracker::SourceRoot root;
+    root.root_type = context.storage->InternString("ROOT");
+    root.object_ids.emplace_back(kObjCleaner);
+    tracker.AddRoot(kSeqId, kPid, kTimestamp, std::move(root));
+  }
+
   tracker.FinalizeProfile(kSeqId);
 
   const auto& objs_table = context.storage->heap_graph_object_table();
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 5072bad..952184a 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -306,6 +306,14 @@
     } else {
       auto raw_cmdline = proc.cmdline();
       base::StringView argv0 = raw_cmdline ? *raw_cmdline : base::StringView();
+      // Chrome child process overwrites /proc/self/cmdline and replaces all
+      // '\0' with ' '. This makes argv0 contain the full command line. Extract
+      // the actual argv0 if it's Chrome.
+      static const char kChromeBinary[] = "/chrome ";
+      auto pos = argv0.find(kChromeBinary);
+      if (pos != base::StringView::npos) {
+        argv0 = argv0.substr(0, pos + strlen(kChromeBinary) - 1);
+      }
 
       std::string cmdline_str;
       for (auto cmdline_it = raw_cmdline; cmdline_it;) {
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index 7ddbf2a..c2b3592 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -30,6 +30,7 @@
   "android/android_hwui_threads.sql",
   "android/android_mem.sql",
   "android/android_mem_unagg.sql",
+  "android/android_netperf.sql",
   "android/android_ion.sql",
   "android/composer_execution.sql",
   "android/composition_layers.sql",
@@ -84,6 +85,7 @@
   "chrome/cpu_time_by_rail_mode.sql",
   "chrome/estimated_power_by_category.sql",
   "chrome/estimated_power_by_rail_mode.sql",
+  "chrome/sufficient_chrome_processes.sql",
   "chrome/gesture_jank.sql",
   "chrome/gesture_flow_event.sql",
   "chrome/gesture_flow_event_queuing_delay.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_netperf.sql b/src/trace_processor/metrics/sql/android/android_netperf.sql
new file mode 100644
index 0000000..f7d8ae5
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_netperf.sql
@@ -0,0 +1,93 @@
+--
+-- Copyright 2021 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
+--
+--     https://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.
+
+DROP VIEW IF EXISTS rx_packets;
+CREATE VIEW rx_packets AS
+  SELECT
+    ts,
+    RTRIM(name, " Received KB") AS dev,
+    EXTRACT_ARG(arg_set_id, 'cpu') AS cpu,
+    EXTRACT_ARG(arg_set_id, 'len') AS len
+  FROM counter c
+  LEFT JOIN counter_track t
+    ON c.track_id = t.id
+  WHERE name GLOB "* Received KB"
+  ORDER BY ts DESC;
+
+DROP VIEW IF EXISTS device_total_ingress_traffic;
+CREATE VIEW device_total_ingress_traffic AS
+  SELECT
+    dev,
+    MIN(ts) AS start_ts,
+    MAX(ts) AS end_ts,
+    IIF((MAX(ts) - MIN(ts)) > 10000000, MAX(ts)-MIN(ts), 10000000) AS interval,
+    count(1) AS packets,
+    SUM(len) AS bytes
+  FROM rx_packets
+  GROUP BY dev;
+
+DROP VIEW IF EXISTS device_per_core_ingress_traffic;
+CREATE VIEW device_per_core_ingress_traffic AS
+  SELECT
+    dev,
+    AndroidNetworkMetric_CorePacketStatistic(
+      'id', cpu,
+      'packet_statistic', AndroidNetworkMetric_PacketStatistic(
+        'packets', count(1),
+        'bytes', SUM(len),
+        'first_packet_timestamp_ns', MIN(ts),
+        'last_packet_timestamp_ns', MAX(ts),
+        'interval_ns', IIF((MAX(ts)-MIN(ts))>10000000, MAX(ts)-MIN(ts), 10000000),
+        'data_rate_kbps', (SUM(len)*8)/(IIF((MAX(ts)-MIN(ts))>10000000, MAX(ts)-MIN(ts), 10000000)/1e9)/1024
+      )
+    ) AS proto
+  FROM rx_packets
+  GROUP BY dev, cpu;
+
+DROP VIEW IF EXISTS device_ingress_traffic_statistic;
+CREATE VIEW device_ingress_traffic_statistic AS
+  SELECT
+    AndroidNetworkMetric_NetDevice(
+      'name', dev,
+      'rx', AndroidNetworkMetric_Rx(
+        'total', AndroidNetworkMetric_PacketStatistic(
+          'packets', packets,
+          'bytes', bytes,
+          'first_packet_timestamp_ns', start_ts,
+          'last_packet_timestamp_ns', end_ts,
+          'interval_ns', interval,
+          'data_rate_kbps', (bytes*8)/(interval/1e9)/1024
+        ),
+        'core', (
+          SELECT
+            RepeatedField(proto)
+          FROM device_per_core_ingress_traffic
+          WHERE device_per_core_ingress_traffic.dev = device_total_ingress_traffic.dev
+        )
+      )
+    ) AS proto
+  FROM device_total_ingress_traffic
+  ORDER BY dev;
+
+DROP VIEW IF EXISTS android_netperf_output;
+CREATE VIEW android_netperf_output AS
+  SELECT AndroidNetworkMetric(
+    'net_devices', (
+      SELECT
+        RepeatedField(proto)
+      FROM device_ingress_traffic_statistic
+    )
+  );
+
diff --git a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
index c13a051..8756d27 100644
--- a/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
+++ b/src/trace_processor/metrics/sql/chrome/gesture_jank.sql
@@ -24,40 +24,9 @@
 --          active development and the values & meaning might change without
 --          notice.
 
--- Get all chrome processes and threads tables set up.
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-
--- When working on InputLatency events we need to ensure we have all the events
--- from the browser, renderer, and GPU processes. This query isn't quite
--- perfect. In system tracing we could have 3 browser processes all in the
--- background and this would match, but for now its the best we can do (renderer
--- and GPU names on android are quite complicated, but this should filter 99%
--- (citation needed) of what we want.
---
--- See b/151077536 for historical context.
--- TODO(b/197841224): Refactor or remove this table.
-DROP VIEW IF EXISTS sufficient_chrome_processes;
-CREATE VIEW sufficient_chrome_processes AS
-  SELECT
-    CASE WHEN (
-      SELECT COUNT(*) FROM chrome_process) = 0
-    THEN
-      FALSE
-    ELSE (
-      SELECT COUNT(*) >= 3 FROM (
-        SELECT name FROM chrome_process
-        WHERE
-          name GLOB "Browser" OR
-          name GLOB "Renderer" OR
-          name GLOB "Gpu" OR
-          name GLOB 'com.android.chrome*' OR
-          name GLOB 'com.chrome.beta*' OR
-          name GLOB 'com.chrome.dev*' OR
-          name GLOB 'com.chrome.canary*' OR
-          name GLOB 'com.google.android.apps.chrome*' OR
-          name GLOB 'org.chromium.chrome*'
-        GROUP BY name
-    )) END AS have_enough_chrome_processes;
+-- Temporarily get the sufficient_chrome_processes view until dependency
+-- is removed
+SELECT RUN_METRIC('chrome/sufficient_chrome_processes.sql');
 
 -- A simple table that checks the time between VSync (this can be used to
 -- determine if we're refreshing at 90 FPS or 60 FPS.
diff --git a/src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql b/src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql
new file mode 100644
index 0000000..c44270e
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/sufficient_chrome_processes.sql
@@ -0,0 +1,48 @@
+--
+-- Copyright 2021 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
+--
+--     https://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.
+--
+-- Get all chrome processes and threads tables set up.
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+
+-- When working on InputLatency events we need to ensure we have all the events
+-- from the browser, renderer, and GPU processes. This query isn't quite
+-- perfect. In system tracing we could have 3 browser processes all in the
+-- background and this would match, but for now its the best we can do (renderer
+-- and GPU names on android are quite complicated, but this should filter 99%
+-- (citation needed) of what we want.
+--
+-- See b/151077536 for historical context.
+DROP VIEW IF EXISTS sufficient_chrome_processes;
+CREATE VIEW sufficient_chrome_processes AS
+  SELECT
+    CASE WHEN (
+      SELECT COUNT(*) FROM chrome_process) = 0
+    THEN
+      FALSE
+    ELSE (
+      SELECT COUNT(*) >= 3 FROM (
+        SELECT name FROM chrome_process
+        WHERE
+          name GLOB "Browser" OR
+          name GLOB "Renderer" OR
+          name GLOB "Gpu" OR
+          name GLOB 'com.android.chrome*' OR
+          name GLOB 'com.chrome.beta*' OR
+          name GLOB 'com.chrome.dev*' OR
+          name GLOB 'com.chrome.canary*' OR
+          name GLOB 'com.google.android.apps.chrome*' OR
+          name GLOB 'org.chromium.chrome*'
+        GROUP BY name
+    )) END AS have_enough_chrome_processes;
\ No newline at end of file
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
index 167645f..9ade464 100644
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
+++ b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1 b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
index 5d91f78..1a51f76 100644
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
+++ b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
@@ -2,5 +2,5 @@
 // SHA1(tools/gen_binary_descriptors)
 // 9fc6d77de57ec76a80b76aa282f4c7cf5ce55eec
 // SHA1(protos/perfetto/metrics/metrics.proto)
-// fe8af2b2dce211830488daf2357aea79b4b2a539
+// 1653b1ab1e7701e7a30c606e357ab1957fa2fd48
   
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
index 86c5f5e..eb03abe 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
@@ -1 +1 @@
-0c1ab8b9a3d60c59e43fc4be2f7d6f41a5a0bc81b7a5e5693d8d933952965783
\ No newline at end of file
+8ad83552afc9337975295a49f1e204986e7d3e0852d4e427988640fcb9b453e4
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
index 3db4e21..e532b12 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_load.png.sha256
@@ -1 +1 @@
-615f7f108325d458f288e4669c6aef2ae6a9f2e38e380119a61e3dfaca46c185
\ No newline at end of file
+f6eec7a2f399fbb9e6218bb69c3afcbfcb69971540d09e80c2c4672f507b505a
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
index c44a1c0..38d7127 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
@@ -1 +1 @@
-babc1a1b16f85e2746e157705987fddd90b680ac24ed69600c4709acca997d33
\ No newline at end of file
+3a98fbfe4650915c6bf2bf807f41d1432a071f90fb7ddc7d07f5bd7e9496f1a9
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
index 6211277..982af40 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -1 +1 @@
-5c76ac76334433ef5ca847f47f0020d57d0bb78a6bc3741c7e4e1e9ad4e32c81
\ No newline at end of file
+cd37b947cb5a9c4275b096f6dee36a0166dda4d9e27a5838a4969a3e8b590a21
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256 b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
index 58243f3..9972f70 100644
--- a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
@@ -1 +1 @@
-29cdb8b1a7fb2df704fa16fb9d342aef9f61d17dea58c5c2a57ccc0bda3b874f
\ No newline at end of file
+11b4adcbe2171d25356df8bf15e96c2d87a15a9e6e59f9b6349bbfa919620255
\ No newline at end of file
diff --git a/test/trace_processor/network/index b/test/trace_processor/network/index
index a252836..73f9898 100644
--- a/test/trace_processor/network/index
+++ b/test/trace_processor/network/index
@@ -1,2 +1,3 @@
 # Network performance
 netif_receive_skb.textproto netif_receive_skb.sql netif_receive_skb.out
+netperf_metric.textproto android_netperf netperf_metric.out
diff --git a/test/trace_processor/network/netperf_metric.out b/test/trace_processor/network/netperf_metric.out
new file mode 100644
index 0000000..89ca722
--- /dev/null
+++ b/test/trace_processor/network/netperf_metric.out
@@ -0,0 +1,61 @@
+android_netperf{
+  net_devices {
+    name: "rmnet0"
+    rx {
+      total {
+        packets: 4
+        bytes: 4096
+        first_packet_timestamp_ns: 100000000
+        last_packet_timestamp_ns: 140000000
+        interval_ns: 40000000
+        data_rate_kbps: 800.0
+      }
+      core {
+        id: 0
+        packet_statistic {
+          packets: 2
+          bytes: 2048
+          first_packet_timestamp_ns: 100000000
+          last_packet_timestamp_ns: 140000000
+          interval_ns: 40000000
+          data_rate_kbps: 400.0
+        }
+      }
+      core {
+        id: 1
+        packet_statistic {
+          packets: 2
+          bytes: 2048
+          first_packet_timestamp_ns: 120000000
+          last_packet_timestamp_ns: 140000000
+          interval_ns: 20000000
+          data_rate_kbps: 800.0
+        }
+      }
+    }
+  }
+  net_devices {
+    name: "wlan"
+    rx {
+      total {
+        packets: 1
+        bytes: 512
+        first_packet_timestamp_ns: 100000000
+        last_packet_timestamp_ns: 100000000
+        interval_ns: 10000000
+        data_rate_kbps: 400.0
+      }
+      core {
+        id: 4
+        packet_statistic {
+          packets: 1
+          bytes: 512
+          first_packet_timestamp_ns: 100000000
+          last_packet_timestamp_ns: 100000000
+          interval_ns: 10000000
+          data_rate_kbps: 400.0
+        }
+      }
+    }
+  }
+}
diff --git a/test/trace_processor/network/netperf_metric.textproto b/test/trace_processor/network/netperf_metric.textproto
new file mode 100644
index 0000000..ffa3ad1
--- /dev/null
+++ b/test/trace_processor/network/netperf_metric.textproto
@@ -0,0 +1,65 @@
+ packet {
+  ftrace_events {
+    cpu: 0
+    event {
+      timestamp: 100000000
+      pid: 200
+      netif_receive_skb {
+        name: "rmnet0"
+        len: 1024
+      }
+    }
+  }
+}
+packet {
+  ftrace_events {
+    cpu: 1
+    event {
+      timestamp: 120000000
+      pid: 300
+      netif_receive_skb {
+        name: "rmnet0"
+        len: 1024
+      }
+    }
+  }
+}
+packet {
+  ftrace_events {
+    cpu: 0
+    event {
+      timestamp: 140000000
+      pid: 400
+      netif_receive_skb {
+        name: "rmnet0"
+        len: 1024
+      }
+    }
+  }
+}
+packet {
+  ftrace_events {
+    cpu: 1
+    event {
+      timestamp: 140000000
+      pid: 500
+      netif_receive_skb {
+        name: "rmnet0"
+        len: 1024
+      }
+    }
+  }
+}
+packet {
+  ftrace_events {
+    cpu: 4
+    event {
+      timestamp: 100000000
+      pid: 600
+      netif_receive_skb {
+        name: "wlan"
+        len: 512
+      }
+    }
+  }
+}
diff --git a/test/trace_processor/profiling/heap_graph_native_size.out b/test/trace_processor/profiling/heap_graph_native_size.out
new file mode 100644
index 0000000..c0d6b61
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_native_size.out
@@ -0,0 +1,3 @@
+"type_name","native_size"
+"android.graphics.Bitmap",123456
+"android.os.BinderProxy",0
diff --git a/test/trace_processor/profiling/heap_graph_native_size.sql b/test/trace_processor/profiling/heap_graph_native_size.sql
new file mode 100644
index 0000000..fcef1f6
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_native_size.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2021 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
+--
+--     https://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.
+--
+select c.name as type_name,
+       o.native_size
+from heap_graph_object o join heap_graph_class c on o.type_id = c.id
+where o.root_type = "ROOT_JAVA_FRAME"
diff --git a/test/trace_processor/profiling/heap_graph_native_size.textproto b/test/trace_processor/profiling/heap_graph_native_size.textproto
new file mode 100644
index 0000000..00a2bc6
--- /dev/null
+++ b/test/trace_processor/profiling/heap_graph_native_size.textproto
@@ -0,0 +1,217 @@
+packet {
+  trusted_packet_sequence_id: 999
+  timestamp: 10
+  heap_graph {
+    pid: 2
+    types {
+      id: 54
+      location_id: 5
+      class_name: "java.lang.Object"
+      object_size: 8
+      kind: KIND_NOREFERENCES
+      classloader_id: 0
+    }
+    types {
+      id: 12171
+      location_id: 5
+      class_name: "java.lang.ref.Reference"
+      object_size: 24
+      superclass_id: 54
+      reference_field_id: 1 # pendingNext
+      reference_field_id: 2 # queue
+      reference_field_id: 3 # queueNext
+      reference_field_id: 15420 # referent
+      kind: KIND_NORMAL
+      classloader_id: 0
+    }
+    types {
+      id: 11645
+      location_id: 5
+      class_name: "java.lang.ref.PhantomReference"
+      object_size: 24
+      superclass_id: 12171
+      kind: KIND_PHANTOM_REFERENCE
+      classloader_id: 0
+    }
+    types {
+      id: 17
+      location_id: 5
+      class_name: "sun.misc.Cleaner"
+      object_size: 36
+      superclass_id: 11645
+      reference_field_id: 14946 # next
+      reference_field_id: 14947 # prev
+      reference_field_id: 14948 # thunk
+      kind: KIND_PHANTOM_REFERENCE
+      classloader_id: 0
+    }
+    types {
+      id: 11646
+      location_id: 5
+      class_name: "java.lang.Class<sun.misc.Cleaner>"
+    }
+    types {
+      id: 16
+      location_id: 10
+      class_name: "libcore.util.NativeAllocationRegistry$CleanerThunk"
+      object_size: 24
+      superclass_id: 54
+      reference_field_id: 19501 # this$0
+      kind: KIND_NORMAL
+      classloader_id: 0
+    }
+    types {
+      id: 778
+      location_id: 10
+      class_name: "libcore.util.NativeAllocationRegistry"
+      object_size: 32
+      superclass_id: 54
+      reference_field_id: 19502
+      kind: KIND_NORMAL
+      classloader_id: 0
+    }
+    types {
+      id: 777
+      location_id: 6
+      class_name: "android.graphics.Bitmap"
+      object_size: 46
+      superclass_id: 54
+      # References omitted
+      kind: KIND_NORMAL
+      classloader_id: 0
+    }
+    types {
+      id: 15
+      location_id: 8
+      class_name: "android.os.BinderProxy"
+      object_size: 17
+      superclass_id: 54
+      kind: KIND_NOREFERENCES
+      classloader_id: 0
+    }
+    objects {
+      id: 0x1
+      type_id: 777 # android.graphics.Bitmap
+    }
+    objects {
+      id: 0x2
+      type_id: 15 # android.os.BinderProxy
+    }
+    objects {
+      id: 0x3
+      type_id: 778 # libcore.util.NativeAllocationRegistry
+      reference_object_id: 0x0 # classLoader omitted
+      native_allocation_registry_size_field: 123456
+    }
+    objects {
+      id: 0x4
+      type_id: 16 # libcore.util.NativeAllocationRegistry$CleanerThunk
+      reference_object_id: 0x3 # this$0
+    }
+    objects {
+      id: 0x5
+      type_id: 16 # libcore.util.NativeAllocationRegistry$CleanerThunk
+      reference_object_id: 0x3 # this$0
+    }
+    # This Cleaner has not been deleted: it's reachable from a root (through the
+    # sun.misc.Cleaner.first static field).
+    objects {
+      id: 0x6
+      type_id: 17 # sun.misc.Cleaner
+      reference_object_id: 0x0 # next
+      reference_object_id: 0x0 # prev
+      reference_object_id: 0x4 # thunk
+      reference_object_id: 0x0 # pendingNext
+      reference_object_id: 0x0 # queue
+      reference_object_id: 0x0 # queueNext
+      reference_object_id: 0x1 # referent
+    }
+    # This Cleaner has been deleted: it's not reachable from a root and its .prev
+    # and .next point to this.
+    objects {
+      id: 0x7
+      type_id: 17 # sun.misc.Cleaner
+      reference_object_id: 0x7 # next
+      reference_object_id: 0x7 # prev
+      reference_object_id: 0x5 # thunk
+      reference_object_id: 0x0 # pendingNext
+      reference_object_id: 0x0 # queue
+      reference_object_id: 0x0 # queueNext
+      reference_object_id: 0x2 # referent
+    }
+    objects {
+      id: 0x8
+      type_id: 11646 # java.lang.Class<sun.misc.Cleaner>
+      self_size: 288
+      # omitted fields
+      reference_field_id: 14950 # first
+      reference_object_id: 0x6
+    }
+    roots {
+      object_ids: 0x8
+      root_type: ROOT_STICKY_CLASS
+    }
+    roots {
+      object_ids: 0x1
+      object_ids: 0x2
+      root_type: ROOT_JAVA_FRAME
+    }
+    field_names {
+      iid: 1
+      str: "java.lang.ref.Reference java.lang.ref.Reference.pendingNext"
+    }
+    field_names {
+      iid: 2
+      str: "java.lang.ref.ReferenceQueue java.lang.ref.Reference.queue"
+    }
+    field_names {
+      iid: 3
+      str: "java.lang.ref.Reference java.lang.ref.Reference.queueNext"
+    }
+    field_names {
+      iid: 14950
+      str: "sun.misc.Cleaner sun.misc.Cleaner.first"
+    }
+    field_names {
+      iid: 15420
+      str: "java.lang.Object java.lang.ref.Reference.referent"
+    }
+    field_names {
+      iid: 14946
+      str: "sun.misc.Cleaner sun.misc.Cleaner.next"
+    }
+    field_names {
+      iid: 14947
+      str: "sun.misc.Cleaner sun.misc.Cleaner.prev"
+    }
+    field_names {
+      iid: 14948
+      str: "java.lang.Runnable sun.misc.Cleaner.thunk"
+    }
+    field_names {
+      iid: 19501
+      str: "libcore.util.NativeAllocationRegistry libcore.util.NativeAllocationRegistry$CleanerThunk.this$0"
+    }
+    field_names {
+      iid: 19502
+      str: "java.lang.ClassLoader libcore.util.NativeAllocationRegistry.classLoader"
+    }
+    location_names {
+      iid: 5
+      str: "/apex/com.android.art/javalib/core-oj.jar"
+    }
+    location_names {
+      iid: 10
+      str: "/apex/com.android.art/javalib/core-libart.jar"
+    }
+    location_names {
+      iid: 6
+      str: "/system/framework/framework.jar"
+    }
+    location_names {
+      iid: 8
+      str: "/system/framework/framework.jar!classes2.dex"
+    }
+    index: 0
+  }
+}
diff --git a/test/trace_processor/profiling/index b/test/trace_processor/profiling/index
index dad2297..07a9340 100644
--- a/test/trace_processor/profiling/index
+++ b/test/trace_processor/profiling/index
@@ -30,6 +30,7 @@
 heap_profile_tracker_twoheaps.textproto heap_profile_tracker_twoheaps.sql heap_profile_tracker_twoheaps.out
 heap_graph_branching.textproto heap_graph_flamegraph_focused.sql heap_graph_flamegraph_focused.out
 heap_graph_superclass.textproto heap_graph_superclass.sql heap_graph_superclass.out
+heap_graph_native_size.textproto heap_graph_native_size.sql heap_graph_native_size.out
 
 # TODO(b/153552977): Stop supporting legacy heap graphs. These never made
 #                    it into a public release, so we should eventually stop
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index af7d95d..f04d473 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -94,10 +94,15 @@
 
 target_host_supported = [
     '//:libperfetto',
+    '//:libperfetto_client_experimental',
     '//protos/perfetto/trace:perfetto_trace_protos',
     '//src/trace_processor:trace_processor_shell',
 ]
 
+target_vendor_available = [
+    '//:libperfetto_client_experimental',
+]
+
 # All module names are prefixed with this string to avoid collisions.
 module_prefix = 'perfetto_'
 
@@ -204,7 +209,6 @@
         ('include_dirs', {'bionic/libc/kernel'}),
     ],
     'perfetto_integrationtests': [
-        ('cflags', {'-fno-finite-loops'}),
         ('test_suites', {'general-tests'}),
         ('test_config', 'PerfettoIntegrationTests.xml'),
     ],
@@ -458,6 +462,7 @@
     self.tools = set()
     self.cmd = None
     self.host_supported = False
+    self.vendor_available = False
     self.init_rc = set()
     self.out = set()
     self.export_include_dirs = set()
@@ -502,6 +507,7 @@
     self._output_field(output, 'tools')
     self._output_field(output, 'cmd', sort=False)
     self._output_field(output, 'host_supported')
+    self._output_field(output, 'vendor_available')
     self._output_field(output, 'init_rc')
     self._output_field(output, 'out')
     self._output_field(output, 'export_include_dirs')
@@ -857,6 +863,7 @@
 
   blueprint.add_module(module)
   module.host_supported = (name_without_toolchain in target_host_supported)
+  module.vendor_available = (name_without_toolchain in target_vendor_available)
   module.init_rc = target_initrc.get(target.name, [])
   module.srcs.update(
       gn_utils.label_to_path(src)
diff --git a/tools/heap_profile b/tools/heap_profile
index ca9e48a..a327133 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -576,7 +576,7 @@
 
 
 # BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v21.0
+# Revision: v22.1
 PERFETTO_PREBUILT_MANIFEST = [{
     'tool':
         'trace_to_text',
@@ -585,11 +585,11 @@
     'file_name':
         'trace_to_text',
     'file_size':
-        7136200,
+        6956224,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/mac-amd64/trace_to_text',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/mac-amd64/trace_to_text',
     'sha256':
-        '17d93547b6c2d81905377e5eb5ac16dc5567df2d1898b84f617c0b723cd7d157',
+        'b40ec5ef358e35ecebacd490dba8320aa3a0bf223da4219f2eba1d3ee7ef3a48',
     'platform':
         'darwin',
     'machine': ['x86_64']
@@ -601,11 +601,11 @@
     'file_name':
         'trace_to_text.exe',
     'file_size':
-        6591488,
+        6663680,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/windows-amd64/trace_to_text.exe',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/windows-amd64/trace_to_text.exe',
     'sha256':
-        'c93daee4fc305daa91aabcb7cad374e7f2870dc2c539259c4e40557901797f8b',
+        '603eb120cbb5db41cf258aa742902ea73ee700d8e6d61900f64fa996d3e1714b',
     'platform':
         'win32',
     'machine': ['amd64']
@@ -617,11 +617,11 @@
     'file_name':
         'trace_to_text',
     'file_size':
-        7671280,
+        7518480,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-amd64/trace_to_text',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-amd64/trace_to_text',
     'sha256':
-        '54858c0d97b13e510d3c62f144d0d8a9959280e4e89c0912b25905fe480a3493',
+        '480e851deb76413f3f7ab113f230bcac19ca4bdd9f5c275f7a4d3cc9318c2db6',
     'platform':
         'linux',
     'machine': ['x86_64']
diff --git a/tools/record_android_trace b/tools/record_android_trace
index 4918dd5..bc3f826 100755
--- a/tools/record_android_trace
+++ b/tools/record_android_trace
@@ -380,7 +380,7 @@
 
 
 # BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v21.0
+# Revision: v22.1
 PERFETTO_PREBUILT_MANIFEST = [{
     'tool':
         'tracebox',
@@ -389,11 +389,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        993356,
+        1034636,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/android-arm/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/android-arm/tracebox',
     'sha256':
-        '86df4b8f210fc7fba88881db340182ecebbdecb9418a36a6c21d62863a77c1f6'
+        'f97875395431b87a38830f73f22b45fedbf5bbcefcdd9f61ab87bcd64b0594e4'
 }, {
     'tool':
         'tracebox',
@@ -402,11 +402,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1522496,
+        1563840,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/android-arm64/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/android-arm64/tracebox',
     'sha256':
-        '22f9a3c750c0ef60281a18a7bc7966427322f3a7d4bb8226bd2c8e37f22100e1'
+        '45cca4277d83b30d33ff5e2bf99120844498d5512bd15c40301157921b3482aa'
 }, {
     'tool':
         'tracebox',
@@ -415,11 +415,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1542172,
+        1591652,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/android-x86/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/android-x86/tracebox',
     'sha256':
-        'cbb1073c515848753d36d8bda81ce4ed97384c4cca90d6d84a294031d83724e5'
+        'fc4f86b92837d3efee4df202da092cd5a945613078b4fe4b8829de0794bf5cdb'
 }, {
     'tool':
         'tracebox',
@@ -428,11 +428,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1780544,
+        1809600,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/android-x64/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/android-x64/tracebox',
     'sha256':
-        'f01656ea00156e64a8cd2aa65c1a8814eebecea6280dc3eb14cfc7b7eefda776'
+        '4610eff243aec24dc0d948503464e466d73045d0383bc625ee820cfd43d3f9a5'
 }]
 
 
diff --git a/tools/trace_processor b/tools/trace_processor
index 0485e59..e532901 100755
--- a/tools/trace_processor
+++ b/tools/trace_processor
@@ -27,7 +27,7 @@
 TOOL_NAME = 'trace_processor_shell'
 
 # BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v21.0
+# Revision: v22.1
 PERFETTO_PREBUILT_MANIFEST = [{
     'tool':
         'trace_processor_shell',
@@ -36,11 +36,11 @@
     'file_name':
         'trace_processor_shell',
     'file_size':
-        7087888,
+        6924200,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/mac-amd64/trace_processor_shell',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/mac-amd64/trace_processor_shell',
     'sha256':
-        'ea06a784e4dfd0b3b6413d26d8e1318be39338b03090680ca5d297285dce7338',
+        '428fc3b61b507053c72c4c65876c18a80c1dae013e5d9c8c4bbe10d08c3dddaf',
     'platform':
         'darwin',
     'machine': ['x86_64']
@@ -52,11 +52,11 @@
     'file_name':
         'trace_processor_shell.exe',
     'file_size':
-        6568960,
+        6655488,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/windows-amd64/trace_processor_shell.exe',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/windows-amd64/trace_processor_shell.exe',
     'sha256':
-        '6c65d66cf87b362e8edfa3cf75c6d08d258ffc880eb52ecb2953e835f7f2d9bd',
+        'e8bd04f3de59a483036f58b86b47d79a9c2bb00f9b1c9590ed1a36250b4f91a0',
     'platform':
         'win32',
     'machine': ['amd64']
@@ -68,11 +68,11 @@
     'file_name':
         'trace_processor_shell',
     'file_size':
-        7631936,
+        7495384,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-amd64/trace_processor_shell',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-amd64/trace_processor_shell',
     'sha256':
-        '2fcdfa192d255ec5995d40ffa049cecca00dfc9c4ab8cefc93b2ef22177b6bbe',
+        '6a7d27e91ab233e82786d1652739dc84e9d86dde5782ec69392f2b5977142596',
     'platform':
         'linux',
     'machine': ['x86_64']
@@ -84,11 +84,11 @@
     'file_name':
         'trace_processor_shell',
     'file_size':
-        4809976,
+        4870060,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-arm/trace_processor_shell',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-arm/trace_processor_shell',
     'sha256':
-        '4998b93731a695c5d669f42d4f2cd236ed0611098a6ac86ef0da711adfb1459e',
+        '3e260ece4b254886b8cf7db0abf05257e747ae69d8d8ea252edb9b518f7cf34a',
     'platform':
         'linux',
     'machine': ['armv6l', 'armv7l', 'armv8l']
@@ -100,11 +100,11 @@
     'file_name':
         'trace_processor_shell',
     'file_size':
-        6669840,
+        6742552,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-arm64/trace_processor_shell',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-arm64/trace_processor_shell',
     'sha256':
-        '3034ec92080f7e600abc2e82d8fec7261258ebdf677022a6880e6678183d539b',
+        'aa4834949fe4b81d7289b9b15e57c4a5437773b356dced7b55afe46655f696c2',
     'platform':
         'linux',
     'machine': ['aarch64']
diff --git a/tools/tracebox b/tools/tracebox
index 78907a0..069053e 100755
--- a/tools/tracebox
+++ b/tools/tracebox
@@ -27,7 +27,7 @@
 TOOL_NAME = 'tracebox'
 
 # BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v21.0
+# Revision: v22.1
 PERFETTO_PREBUILT_MANIFEST = [{
     'tool':
         'tracebox',
@@ -36,11 +36,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1282808,
+        1316160,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/mac-amd64/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/mac-amd64/tracebox',
     'sha256':
-        '65ece42a5032f8c170c6b6ce97bc554ea4b30675f182fd019744c6ec34b0f7e3',
+        '48539da3f73f04fe1c22dcd0aeb8cbed45405df3f4dfb3f2ff4077d6d023463e',
     'platform':
         'darwin',
     'machine': ['x86_64']
@@ -52,11 +52,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1701992,
+        1733320,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-amd64/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-amd64/tracebox',
     'sha256':
-        'f9253b69ccd9cc04f8975efcba41d32b6aef0db3fc5c14d49d3fbb89b789eee1',
+        'b9ab0a535a7e042675f690b0543e158cad01fb8b3e56dc3b7748f44b821ff6d5',
     'platform':
         'linux',
     'machine': ['x86_64']
@@ -68,11 +68,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1701992,
+        1733320,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-amd64/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-amd64/tracebox',
     'sha256':
-        'f9253b69ccd9cc04f8975efcba41d32b6aef0db3fc5c14d49d3fbb89b789eee1',
+        'b9ab0a535a7e042675f690b0543e158cad01fb8b3e56dc3b7748f44b821ff6d5',
     'platform':
         'linux',
     'machine': ['x86_64']
@@ -84,11 +84,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        969560,
+        998700,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-arm/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-arm/tracebox',
     'sha256':
-        '085cfbd48e2ca648d2e76b7f99d43295dd6429d2d47899845e3dd81cdaf493e2',
+        '825a1705f426f333c21679e38676c6118442b7b48379a0e2c2b87f052b3e2f8d',
     'platform':
         'linux',
     'machine': ['armv6l', 'armv7l', 'armv8l']
@@ -100,11 +100,11 @@
     'file_name':
         'tracebox',
     'file_size':
-        1569000,
+        1613536,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-arm64/tracebox',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-arm64/tracebox',
     'sha256':
-        '5dc68c8f68d20dd38f5acf749d9a13a8f347afab648b2b5a6807e374e4970b5d',
+        'e664b2374a6842141b0f8c68838a37d0d387bae576b934db3168b4ae4999f182',
     'platform':
         'linux',
     'machine': ['aarch64']
diff --git a/tools/traceconv b/tools/traceconv
index ebc0273..406bd4d 100755
--- a/tools/traceconv
+++ b/tools/traceconv
@@ -27,7 +27,7 @@
 TOOL_NAME = 'trace_to_text'
 
 # BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v21.0
+# Revision: v22.1
 PERFETTO_PREBUILT_MANIFEST = [{
     'tool':
         'trace_to_text',
@@ -36,11 +36,11 @@
     'file_name':
         'trace_to_text',
     'file_size':
-        7136200,
+        6956224,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/mac-amd64/trace_to_text',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/mac-amd64/trace_to_text',
     'sha256':
-        '17d93547b6c2d81905377e5eb5ac16dc5567df2d1898b84f617c0b723cd7d157',
+        'b40ec5ef358e35ecebacd490dba8320aa3a0bf223da4219f2eba1d3ee7ef3a48',
     'platform':
         'darwin',
     'machine': ['x86_64']
@@ -52,11 +52,11 @@
     'file_name':
         'trace_to_text',
     'file_size':
-        7671280,
+        7518480,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/linux-amd64/trace_to_text',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/linux-amd64/trace_to_text',
     'sha256':
-        '54858c0d97b13e510d3c62f144d0d8a9959280e4e89c0912b25905fe480a3493',
+        '480e851deb76413f3f7ab113f230bcac19ca4bdd9f5c275f7a4d3cc9318c2db6',
     'platform':
         'linux',
     'machine': ['x86_64']
@@ -68,11 +68,11 @@
     'file_name':
         'trace_to_text.exe',
     'file_size':
-        6591488,
+        6663680,
     'url':
-        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v21.0/windows-amd64/trace_to_text.exe',
+        'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v22.1/windows-amd64/trace_to_text.exe',
     'sha256':
-        'c93daee4fc305daa91aabcb7cad374e7f2870dc2c539259c4e40557901797f8b',
+        '603eb120cbb5db41cf258aa742902ea73ee700d8e6d61900f64fa996d3e1714b',
     'platform':
         'win32',
     'machine': ['amd64']
diff --git a/ui/release/channels.json b/ui/release/channels.json
index 359228c..871dc65 100644
--- a/ui/release/channels.json
+++ b/ui/release/channels.json
@@ -2,11 +2,11 @@
   "channels": [
     {
       "name": "stable",
-      "rev": "b4bd17f12d544c7b09cc93c6e7ed22e80ed73e48"
+      "rev": "c3e80bd067b2f16487ca8f3df464f764bfea819a"
     },
     {
       "name": "canary",
-      "rev": "9e3a964c585f3108b1ba2a1b58d4bb6ab96dc1ba"
+      "rev": "4a40a87235f5715a909c0d082ca6a1b318c9b210"
     },
     {
       "name": "autopush",
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 42a3460..36bdaa9 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -541,7 +541,6 @@
   --expanded-background: hsl(215, 22%, 19%);
   --expanded-transparent: hsl(215, 22%, 19%, 0);
   display: grid;
-  align-items: center;
   grid-template-columns: auto 1fr;
   grid-template-rows: 1fr;
   transition: background-color .4s, color .4s;