Configure search to work on arbitrary slice-like tracks

Currently searching only works on tracks with the 'SLICE_TRACK_KIND'
kind tag, which was required for the previous search mechanism. Now,
any tracks can be searched as long as they have name / args_set_id
fields.

This patch replaces the SLICE_TRACK_KIND with two new kinds tags:
- SLICE_TRACK: Indicates that this track represents slice like events
  where ts, dur, name and args_set_id mean what you'd expect, but the
  ids do not necessarily correspond to ids in the slice table.
- SLICE_TABLE_TRACK: Subset of SLICE_TRACK where ids correspond to
  the relevant slices in the slice table.

Change-Id: I174695fedf1f4e353cbf8532cb6d9efdb5261f71
diff --git a/ui/src/components/tracks/debug_tracks.ts b/ui/src/components/tracks/debug_tracks.ts
index c695ce0..167b772 100644
--- a/ui/src/components/tracks/debug_tracks.ts
+++ b/ui/src/components/tracks/debug_tracks.ts
@@ -32,6 +32,7 @@
   SqlTableCounterTrack,
 } from './query_counter_track';
 import {getColorForSlice} from '../colorizer';
+import {SLICE_TRACK} from '../../public/track_kinds';
 
 export interface SqlDataSource {
   // SQL source selecting the necessary data.
@@ -232,6 +233,9 @@
 
     trace.tracks.registerTrack({
       uri,
+      tags: {
+        kinds: [SLICE_TRACK],
+      },
       renderer: SliceTrack.create({
         trace,
         uri,
@@ -274,6 +278,9 @@
 
   trace.tracks.registerTrack({
     uri,
+    tags: {
+      kinds: [SLICE_TRACK],
+    },
     renderer: SliceTrack.create({
       trace,
       uri,
diff --git a/ui/src/components/tracks/visualized_args_tracks.ts b/ui/src/components/tracks/visualized_args_tracks.ts
index 5fb6744..fe5a8a5 100644
--- a/ui/src/components/tracks/visualized_args_tracks.ts
+++ b/ui/src/components/tracks/visualized_args_tracks.ts
@@ -16,7 +16,7 @@
 import {NUM} from '../../trace_processor/query_result';
 import {TrackNode} from '../../public/workspace';
 import {Trace} from '../../public/trace';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK} from '../../public/track_kinds';
 import {createVisualizedArgsTrack} from './visualized_args_track';
 
 const VISUALIZED_ARGS_SLICE_TRACK_URI_PREFIX = 'perfetto.VisualizedArgs';
@@ -89,7 +89,7 @@
         const track = trace.tracks.getTrack(trackNode.uri);
         return (
           track &&
-          track.tags?.kinds?.includes(SLICE_TRACK_KIND) &&
+          track.tags?.kinds?.includes(SLICE_TABLE_TRACK) &&
           track.tags?.trackIds?.includes(trackId)
         );
       },
diff --git a/ui/src/plugins/com.android.AndroidDmabuf/index.ts b/ui/src/plugins/com.android.AndroidDmabuf/index.ts
index c17be34..8cb3f30 100644
--- a/ui/src/plugins/com.android.AndroidDmabuf/index.ts
+++ b/ui/src/plugins/com.android.AndroidDmabuf/index.ts
@@ -18,7 +18,11 @@
 } from '../../components/tracks/query_counter_track';
 import {PerfettoPlugin} from '../../public/plugin';
 import {Trace} from '../../public/trace';
-import {COUNTER_TRACK_KIND, SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {
+  COUNTER_TRACK_KIND,
+  SLICE_TABLE_TRACK,
+  SLICE_TRACK,
+} from '../../public/track_kinds';
 import {TrackNode} from '../../public/workspace';
 import {NUM, NUM_NULL, STR} from '../../trace_processor/query_result';
 import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
@@ -141,7 +145,7 @@
   ctx.tracks.registerTrack({
     uri,
     tags: {
-      kinds: [SLICE_TRACK_KIND],
+      kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
       trackIds: ids,
     },
     renderer: await createTraceProcessorSliceTrack({
diff --git a/ui/src/plugins/com.android.GpuWorkPeriod/index.ts b/ui/src/plugins/com.android.GpuWorkPeriod/index.ts
index 485750d..d98ea80 100644
--- a/ui/src/plugins/com.android.GpuWorkPeriod/index.ts
+++ b/ui/src/plugins/com.android.GpuWorkPeriod/index.ts
@@ -16,7 +16,7 @@
 import {PerfettoPlugin} from '../../public/plugin';
 import {Trace} from '../../public/trace';
 import {TrackNode} from '../../public/workspace';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK, SLICE_TRACK} from '../../public/track_kinds';
 import {SliceTrack} from '../../components/tracks/slice_track';
 import {SourceDataset} from '../../trace_processor/dataset';
 
@@ -77,7 +77,7 @@
         uri,
         tags: {
           trackIds: [trackId],
-          kinds: [SLICE_TRACK_KIND],
+          kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
         },
         renderer: track,
       });
diff --git a/ui/src/plugins/dev.perfetto.Frames/index.ts b/ui/src/plugins/dev.perfetto.Frames/index.ts
index b886ee9..2e93607 100644
--- a/ui/src/plugins/dev.perfetto.Frames/index.ts
+++ b/ui/src/plugins/dev.perfetto.Frames/index.ts
@@ -16,7 +16,7 @@
 import {createAggregationTab} from '../../components/aggregation_adapter';
 import {PerfettoPlugin} from '../../public/plugin';
 import {Trace} from '../../public/trace';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK, SLICE_TRACK} from '../../public/track_kinds';
 import {TrackNode} from '../../public/workspace';
 import {NUM, STR} from '../../trace_processor/query_result';
 import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
@@ -95,7 +95,7 @@
         uri,
         renderer: createExpectedFramesTrack(ctx, uri, maxDepth, trackIds),
         tags: {
-          kinds: [SLICE_TRACK_KIND],
+          kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
           trackIds,
           upid,
         },
@@ -161,7 +161,11 @@
         tags: {
           upid,
           trackIds,
-          kinds: [SLICE_TRACK_KIND, ACTUAL_FRAMES_SLICE_TRACK_KIND],
+          kinds: [
+            SLICE_TRACK,
+            SLICE_TABLE_TRACK,
+            ACTUAL_FRAMES_SLICE_TRACK_KIND,
+          ],
         },
       });
       group?.addChildInOrder(
@@ -187,7 +191,7 @@
           tags: {
             upid,
             trackIds,
-            kinds: [SLICE_TRACK_KIND],
+            kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
           },
         });
         group?.addChildInOrder(
diff --git a/ui/src/plugins/dev.perfetto.KernelTrackEvent/index.ts b/ui/src/plugins/dev.perfetto.KernelTrackEvent/index.ts
index b2ddb3c..c7612d2 100644
--- a/ui/src/plugins/dev.perfetto.KernelTrackEvent/index.ts
+++ b/ui/src/plugins/dev.perfetto.KernelTrackEvent/index.ts
@@ -15,7 +15,11 @@
 import {assertExists} from '../../base/logging';
 import {PerfettoPlugin} from '../../public/plugin';
 import {Trace} from '../../public/trace';
-import {COUNTER_TRACK_KIND, SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {
+  COUNTER_TRACK_KIND,
+  SLICE_TABLE_TRACK,
+  SLICE_TRACK,
+} from '../../public/track_kinds';
 import {TrackNode} from '../../public/workspace';
 import {
   LONG_NULL,
@@ -142,7 +146,7 @@
         ctx.tracks.registerTrack({
           uri,
           tags: {
-            kinds: [SLICE_TRACK_KIND],
+            kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
             trackIds: [trackId],
             upid: upid ?? undefined,
             utid: utid ?? undefined,
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts
index 585a3d3..c13d139 100644
--- a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts
@@ -29,7 +29,11 @@
 import {PerfettoPlugin} from '../../public/plugin';
 import {AreaSelection, areaSelectionsEqual} from '../../public/selection';
 import {Trace} from '../../public/trace';
-import {COUNTER_TRACK_KIND, SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {
+  COUNTER_TRACK_KIND,
+  SLICE_TABLE_TRACK,
+  SLICE_TRACK,
+} from '../../public/track_kinds';
 import {getTrackName} from '../../public/utils';
 import {TrackNode} from '../../public/workspace';
 import {SourceDataset} from '../../trace_processor/dataset';
@@ -374,7 +378,7 @@
         processName,
         upid,
         utid,
-        kind: SLICE_TRACK_KIND,
+        kind: SLICE_TABLE_TRACK,
         threadTrack: utid !== undefined,
       });
       const uri = `/slice_${trackIds[0]}`;
@@ -393,7 +397,7 @@
         uri,
         description: maybeDescriptionRenderer ?? description ?? undefined,
         tags: {
-          kinds: [SLICE_TRACK_KIND],
+          kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
           trackIds: trackIds,
           type: type,
           upid: upid ?? undefined,
@@ -578,7 +582,7 @@
   ): Promise<QueryFlamegraphWithMetrics | undefined> {
     const trackIds = [];
     for (const trackInfo of currentSelection.tracks) {
-      if (!trackInfo?.tags?.kinds?.includes(SLICE_TRACK_KIND)) {
+      if (!trackInfo?.tags?.kinds?.includes(SLICE_TABLE_TRACK)) {
         continue;
       }
       if (trackInfo.tags?.trackIds === undefined) {
@@ -757,11 +761,15 @@
     ctx.search.registerSearchProvider({
       name: 'Slices by name',
       selectTracks(tracks) {
-        return tracks
-          .filter((t) => t.tags?.kinds?.includes(SLICE_TRACK_KIND))
-          .filter((t) =>
-            t.renderer.getDataset?.()?.implements({name: STR_NULL}),
-          );
+        return (
+          tracks
+            // Works on any slice-like track with a name field, doesn't need to
+            // be in the slice table
+            .filter((t) => t.tags?.kinds?.includes(SLICE_TRACK))
+            .filter((t) =>
+              t.renderer.getDataset?.()?.implements({name: STR_NULL}),
+            )
+        );
       },
       async getSearchFilter(searchTerm) {
         return {
@@ -774,9 +782,16 @@
     ctx.search.registerSearchProvider({
       name: 'Slices by id',
       selectTracks(tracks) {
-        return tracks
-          .filter((t) => t.tags?.kinds?.includes(SLICE_TRACK_KIND))
-          .filter((t) => t.renderer.getDataset?.()?.implements({id: NUM_NULL}));
+        return (
+          tracks
+            // Searching by ID is usually used to search for an ID from the
+            // slice table, so we only operate on slice tracks from the slice
+            // table.
+            .filter((t) => t.tags?.kinds?.includes(SLICE_TABLE_TRACK))
+            .filter((t) =>
+              t.renderer.getDataset?.()?.implements({id: NUM_NULL}),
+            )
+        );
       },
       async getSearchFilter(searchTerm) {
         // Attempt to parse the search term as an integer.
@@ -796,11 +811,15 @@
     ctx.search.registerSearchProvider({
       name: 'Slice arguments',
       selectTracks(tracks) {
-        return tracks
-          .filter((t) => t.tags?.kinds?.includes(SLICE_TRACK_KIND))
-          .filter((t) =>
-            t.renderer.getDataset?.()?.implements({arg_set_id: NUM_NULL}),
-          );
+        return (
+          tracks
+            // Again, works on any slice-like track with args, doesn't need to
+            // be in the slice table
+            .filter((t) => t.tags?.kinds?.includes(SLICE_TRACK))
+            .filter((t) =>
+              t.renderer.getDataset?.()?.implements({arg_set_id: NUM_NULL}),
+            )
+        );
       },
       async getSearchFilter(searchTerm) {
         const searchLiteral = escapeSearchQuery(searchTerm);
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/pivot_table_tab.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/pivot_table_tab.ts
index b8308f8..a45f47a 100644
--- a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/pivot_table_tab.ts
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/pivot_table_tab.ts
@@ -22,7 +22,7 @@
   areaSelectionsEqual,
   AreaSelectionTab,
 } from '../../public/selection';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK} from '../../public/track_kinds';
 import {Button} from '../../widgets/button';
 import {Trace} from '../../public/trace';
 import {extensions} from '../../components/extensions';
@@ -46,7 +46,10 @@
     ) {
       this.previousSelection = selection;
       this.trackIds = selection.tracks
-        .filter((track) => track.tags?.kinds?.includes(SLICE_TRACK_KIND))
+        // Can only work from slice table tracks.
+        // TODO(stevegolton): Remove this and just use the aggregations which
+        // can operate on any slice-like tracks.
+        .filter((track) => track.tags?.kinds?.includes(SLICE_TABLE_TRACK))
         .flatMap((track) => track.tags?.trackIds ?? []);
       this.getOrCreateState().filters.setFilters([
         {
diff --git a/ui/src/plugins/dev.perfetto.TrackEvent/index.ts b/ui/src/plugins/dev.perfetto.TrackEvent/index.ts
index 3ac9235..94b709f 100644
--- a/ui/src/plugins/dev.perfetto.TrackEvent/index.ts
+++ b/ui/src/plugins/dev.perfetto.TrackEvent/index.ts
@@ -25,7 +25,11 @@
 } from '../../trace_processor/query_result';
 import {TrackNode} from '../../public/workspace';
 import {assertExists, assertTrue} from '../../base/logging';
-import {COUNTER_TRACK_KIND, SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {
+  COUNTER_TRACK_KIND,
+  SLICE_TABLE_TRACK,
+  SLICE_TRACK,
+} from '../../public/track_kinds';
 import {createTraceProcessorSliceTrack} from '../dev.perfetto.TraceProcessorTrack/trace_processor_slice_track';
 import {TraceProcessorCounterTrack} from '../dev.perfetto.TraceProcessorTrack/trace_processor_counter_track';
 import {getTrackName} from '../../public/utils';
@@ -178,7 +182,7 @@
         continue;
       }
 
-      const kind = isCounter ? COUNTER_TRACK_KIND : SLICE_TRACK_KIND;
+      const kind = isCounter ? COUNTER_TRACK_KIND : SLICE_TABLE_TRACK;
       const trackIds = rawTrackIds.split(',').map((v) => Number(v));
       const trackName = getTrackName({
         name,
@@ -203,7 +207,9 @@
           uri,
           description: description ?? undefined,
           tags: {
-            kinds: [kind],
+            kinds: isCounter
+              ? [COUNTER_TRACK_KIND]
+              : [SLICE_TRACK, SLICE_TABLE_TRACK],
             trackIds: [trackIds[0]],
             upid: upid ?? undefined,
             utid: utid ?? undefined,
diff --git a/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts b/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts
index 09a06db..2351e05 100644
--- a/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts
+++ b/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts
@@ -16,7 +16,7 @@
 import {Trace} from '../../public/trace';
 import {PerfettoPlugin} from '../../public/plugin';
 import {createTraceProcessorSliceTrack} from '../dev.perfetto.TraceProcessorTrack/trace_processor_slice_track';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK, SLICE_TRACK} from '../../public/track_kinds';
 import {TrackNode} from '../../public/workspace';
 import TraceProcessorTrackPlugin from '../dev.perfetto.TraceProcessorTrack';
 
@@ -70,7 +70,7 @@
           trackIds: [trackId],
         }),
         tags: {
-          kinds: [SLICE_TRACK_KIND],
+          kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
           trackIds: [trackId],
         },
       });
diff --git a/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts b/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts
index 5544ca6..841e5e8 100644
--- a/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts
+++ b/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts
@@ -17,7 +17,7 @@
 import {PerfettoPlugin} from '../../public/plugin';
 import {Trace} from '../../public/trace';
 import {TrackNode} from '../../public/workspace';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK, SLICE_TRACK} from '../../public/track_kinds';
 import {SuspendResumeDetailsPanel} from './suspend_resume_details';
 import ThreadPlugin from '../dev.perfetto.Thread';
 import TraceProcessorTrackPlugin from '../dev.perfetto.TraceProcessorTrack';
@@ -66,7 +66,7 @@
       uri,
       tags: {
         trackIds,
-        kinds: [SLICE_TRACK_KIND],
+        kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
       },
       renderer: await createTraceProcessorSliceTrack({
         trace: ctx,
diff --git a/ui/src/plugins/org.kernel.Wattson/index.ts b/ui/src/plugins/org.kernel.Wattson/index.ts
index 783cc2f..98cda72 100644
--- a/ui/src/plugins/org.kernel.Wattson/index.ts
+++ b/ui/src/plugins/org.kernel.Wattson/index.ts
@@ -20,7 +20,7 @@
 import {SliceTrack} from '../../components/tracks/slice_track';
 import {PerfettoPlugin} from '../../public/plugin';
 import {Trace} from '../../public/trace';
-import {SLICE_TRACK_KIND} from '../../public/track_kinds';
+import {SLICE_TABLE_TRACK, SLICE_TRACK} from '../../public/track_kinds';
 import {TrackNode} from '../../public/workspace';
 import {Engine} from '../../trace_processor/engine';
 import {SourceDataset} from '../../trace_processor/dataset';
@@ -183,7 +183,7 @@
   ctx.tracks.registerTrack({
     uri,
     tags: {
-      kinds: [SLICE_TRACK_KIND],
+      kinds: [SLICE_TRACK, SLICE_TABLE_TRACK],
     },
     renderer: track,
   });
diff --git a/ui/src/public/track_kinds.ts b/ui/src/public/track_kinds.ts
index b200918..4dbf4fd 100644
--- a/ui/src/public/track_kinds.ts
+++ b/ui/src/public/track_kinds.ts
@@ -17,6 +17,21 @@
 // ton of circular imports.
 export const CPU_SLICE_TRACK_KIND = 'CpuSliceTrack';
 export const THREAD_STATE_TRACK_KIND = 'ThreadStateTrack';
-export const SLICE_TRACK_KIND = 'SliceTrack';
 export const COUNTER_TRACK_KIND = 'CounterTrack';
 export const ANDROID_LOGS_TRACK_KIND = 'AndroidLogTrack';
+
+// This type indicates that a track represents slice-like data and that it's
+// dataset's columns are as such:
+// - id: A unique identifier for the slice
+// - ts: A timestamp indicating the start of the slice
+// - dur: (Optional) A duration indicating the length of the slice
+// - name: (Optional) The name of the slice
+export const SLICE_TRACK = 'SliceTrack';
+
+// This type indicates the id of each event in this track corresponds to a row
+// in the `slice` table. Users of this track kind can expect to be able to query
+// the `slice` table for more information about each event.
+// TODO(stevegolton): Eventually, users should not have to make this assumption
+// and should just be able to operate on the dataset provided by the track, but
+// some legacy systems still rely on this: e.g flows.
+export const SLICE_TABLE_TRACK = 'SliceTableTrack';