Merge "COPYBARA_IMPORT=Project import generated by Copybara." into main
diff --git a/CHANGELOG b/CHANGELOG
index 42b024c..c82dcfd 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,7 +35,36 @@
     * Added `CREATE PERFETTO INDEX` to add sqlite-like indexes to Perfetto
       tables. Has the same API as `CREATE INDEX`.
   UI:
-    *
+    * Updated to Typescript 5.5.2, lib es2022, & upreved various packages.
+    * Made `Disposable`, `DisposableStack`, and their async variants available
+      to use in the UI.
+    * Vastly improved flamegraph.
+    * Added track filter which can be used to search for tracks by name.
+    * Added Wattson cpu power estimation plugin.
+    * Added option to show thread slice ancestor/descendant slices in thread
+      slice details panel context menu.
+    * Added feature where plugin can ask tracks to be automatically pinned when
+      adding tracks on trace load.
+    * Fixed inconsistent y-range for all CPU SS tracks.
+    * Switched to using explicit de/serialization when creating/loading
+      permalinks.
+    * Improved sched slice details query efficiency.
+    * Added `TagInput` widget.
+    * Added `ui/format-sources` script to run eslint and prettier in one go.
+    * Reduced number of circular imports.
+    * Added `SharedAsyncDisposable` for management of shared async resources.
+    * Fixed rendering of negative counter tracks.
+    * Improved data loss notification using a popup
+    * Tidied up `TrackDescriptor`.
+    * Added Android trace probes for ChromeOS
+    * Added feature to try reconnect when websocket connection is lost.
+    * Fixed bug in 1ns event rendering.
+    * Tidied up details panel font sizes and weights.
+    * Added segmented buttons widget.
+    * Added 'main thread' chip to main thread tracks.
+    * Added plugin API to add menu items to the sidebar.
+    * Added `onTraceReady` plugin hook.
+    * Various clean-ups and bugfixes.
   SDK:
     *
 
diff --git a/python/tools/check_ratchet.py b/python/tools/check_ratchet.py
index 77150a4..317508d 100755
--- a/python/tools/check_ratchet.py
+++ b/python/tools/check_ratchet.py
@@ -36,7 +36,7 @@
 
 from dataclasses import dataclass
 
-EXPECTED_ANY_COUNT = 65
+EXPECTED_ANY_COUNT = 61
 EXPECTED_RUN_METRIC_COUNT = 5
 
 ROOT_DIR = os.path.dirname(
diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/cpu_idle.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/cpu_idle.sql
index 78f0781..e59f724 100644
--- a/src/trace_processor/perfetto_sql/stdlib/wattson/cpu_idle.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/wattson/cpu_idle.sql
@@ -13,7 +13,7 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-INCLUDE PERFETTO MODULE linux.cpu.idle;
+INCLUDE PERFETTO MODULE counters.intervals;
 INCLUDE PERFETTO MODULE wattson.device_infos;
 
 -- Get the corresponding deep idle time offset based on device and CPU.
@@ -34,17 +34,25 @@
     SELECT
       ts,
       dur,
-      idle,
-      lag(idle) OVER (PARTITION BY track_id ORDER BY ts) AS idle_prev,
-      cpu
-    FROM cpu_idle_counters
+      value AS idle,
+      cli.value - cli.delta_value AS idle_prev,
+      cct.cpu
+    -- Same as cpu_idle_counters, but extracts some additional info that isn't
+    -- nominally present in cpu_idle_counters, such that the already calculated
+    -- lag values are reused instead of recomputed
+    FROM counter_leading_intervals!((
+      SELECT c.*
+      FROM counter c
+      JOIN cpu_counter_track cct ON cct.id = c.track_id AND cct.name = 'cpuidle'
+    )) AS cli
+    JOIN cpu_counter_track AS cct ON cli.track_id = cct.id
   ),
   -- Adjusted ts if applicable, which makes the current deep idle state
   -- slightly shorter.
   idle_mod AS (
     SELECT
       IIF(
-        idle_prev = -1 AND idle = 1,
+        idle_prev = 4294967295 AND idle = 1,
         IIF(dur > offset_ns, ts + offset_ns, ts + dur),
         ts
       ) as ts,
@@ -54,13 +62,13 @@
       cpu,
       idle
     FROM idle_prev
-    JOIN _filtered_deep_idle_offsets using (cpu)
+    JOIN _filtered_deep_idle_offsets USING (cpu)
   )
 SELECT
   ts,
   lead(ts, 1, trace_end()) OVER (PARTITION BY cpu ORDER by ts) - ts as dur,
   cpu,
-  idle
+  cast_int!(IIF(idle = 4294967295, -1, idle)) AS idle
 FROM idle_mod
 WHERE ts != ts_next;
 
diff --git a/ui/src/frontend/thread_slice_details_tab.ts b/ui/src/frontend/thread_slice_details_tab.ts
index 0c19139..bf2f800 100644
--- a/ui/src/frontend/thread_slice_details_tab.ts
+++ b/ui/src/frontend/thread_slice_details_tab.ts
@@ -364,7 +364,7 @@
       return m(
         Section,
         {title: 'Preceding Flows'},
-        m(BasicTable, {
+        m(BasicTable<Flow>, {
           columns: [
             {
               title: 'Slice',
@@ -411,7 +411,7 @@
       return m(
         Section,
         {title: 'Following Flows'},
-        m(BasicTable, {
+        m(BasicTable<Flow>, {
           columns: [
             {
               title: 'Slice',
diff --git a/ui/src/frontend/widgets/sql/table/table.ts b/ui/src/frontend/widgets/sql/table/table.ts
index 7d3d239..890800a 100644
--- a/ui/src/frontend/widgets/sql/table/table.ts
+++ b/ui/src/frontend/widgets/sql/table/table.ts
@@ -188,7 +188,7 @@
 
     return [
       m('div', this.renderFilters()),
-      m(BasicTable, {
+      m(BasicTable<Row>, {
         data: rows,
         columns: this.state.getSelectedColumns().map((column, i) => ({
           title: this.renderColumnHeader(column, i),
diff --git a/ui/src/widgets/basic_table.ts b/ui/src/widgets/basic_table.ts
index baa4601..5231a9f 100644
--- a/ui/src/widgets/basic_table.ts
+++ b/ui/src/widgets/basic_table.ts
@@ -15,28 +15,24 @@
 import m from 'mithril';
 
 export interface ColumnDescriptor<T> {
-  title: m.Children;
+  readonly title: m.Children;
   render: (row: T) => m.Children;
 }
 
 export interface TableAttrs<T> {
-  data: T[];
-  columns: ColumnDescriptor<T>[];
+  readonly data: ReadonlyArray<T>;
+  readonly columns: ReadonlyArray<ColumnDescriptor<T>>;
 }
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export class BasicTable implements m.ClassComponent<TableAttrs<any>> {
-  renderColumnHeader(
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    _vnode: m.Vnode<TableAttrs<any>>,
-    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    column: ColumnDescriptor<any>,
+export class BasicTable<T> implements m.ClassComponent<TableAttrs<T>> {
+  private renderColumnHeader(
+    _vnode: m.Vnode<TableAttrs<T>>,
+    column: ColumnDescriptor<T>,
   ): m.Children {
     return m('td', column.title);
   }
 
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  view(vnode: m.Vnode<TableAttrs<any>>): m.Child {
+  view(vnode: m.Vnode<TableAttrs<T>>): m.Children {
     const attrs = vnode.attrs;
 
     return m(