Cleanup way of adding debug track from PinAndroidMetrics plugin

As we're using onTraceReady (after aosp/3197353), we don't need the "static"/"debug" distinction anymore.

+ Use custom name with random id for a temporary table. This fixes the case of multiple metrics added (as they were added later, and subsequent metrics were overriding the previous table)

Bug: 354119654
Bug: 351998803
Change-Id: I2779a56ef16d68c42906c81a014bb854410c9cf4
diff --git a/ui/src/plugins/dev.perfetto.AndroidCujs/index.ts b/ui/src/plugins/dev.perfetto.AndroidCujs/index.ts
index 24d90bf..66e42f8 100644
--- a/ui/src/plugins/dev.perfetto.AndroidCujs/index.ts
+++ b/ui/src/plugins/dev.perfetto.AndroidCujs/index.ts
@@ -15,27 +15,23 @@
 import {SimpleSliceTrackConfig} from '../../frontend/simple_slice_track';
 import {addDebugSliceTrack} from '../../public';
 import {Plugin, PluginContextTrace, PluginDescriptor} from '../../public';
-import {addAndPinSliceTrack, TrackType} from './trackUtils';
+import {addAndPinSliceTrack} from './trackUtils';
 
 /**
  * Adds the Debug Slice Track for given Jank CUJ name
  *
  * @param {PluginContextTrace} ctx For properties and methods of trace viewer
  * @param {string} trackName Display Name of the track
- * @param {TrackType} type Track type for jank CUJ slice track
  * @param {string | string[]} cujNames List of Jank CUJs to pin
- * @param {string} uri Identifier for the track in case of 'static' type
  */
 export function addJankCUJDebugTrack(
   ctx: PluginContextTrace,
   trackName: string,
-  type: TrackType,
   cujNames?: string | string[],
-  uri?: string,
 ) {
   const jankCujTrackConfig: SimpleSliceTrackConfig =
     generateJankCujTrackConfig(cujNames);
-  addAndPinSliceTrack(ctx, jankCujTrackConfig, trackName, type, uri);
+  addAndPinSliceTrack(ctx, jankCujTrackConfig, trackName);
 }
 
 const JANK_CUJ_QUERY_PRECONDITIONS = `
@@ -224,7 +220,7 @@
       name: 'Add track: Android jank CUJs',
       callback: () => {
         ctx.engine.query(JANK_CUJ_QUERY_PRECONDITIONS).then(() => {
-          addJankCUJDebugTrack(ctx, 'Jank CUJs', 'debug');
+          addJankCUJDebugTrack(ctx, 'Jank CUJs');
         });
       },
     });
diff --git a/ui/src/plugins/dev.perfetto.AndroidCujs/trackUtils.ts b/ui/src/plugins/dev.perfetto.AndroidCujs/trackUtils.ts
index 2b108d2..e661076 100644
--- a/ui/src/plugins/dev.perfetto.AndroidCujs/trackUtils.ts
+++ b/ui/src/plugins/dev.perfetto.AndroidCujs/trackUtils.ts
@@ -13,20 +13,13 @@
 // limitations under the License.
 
 import {globals} from '../../frontend/globals';
-import {
-  SimpleSliceTrack,
-  SimpleSliceTrackConfig,
-} from '../../frontend/simple_slice_track';
+import {SimpleSliceTrackConfig} from '../../frontend/simple_slice_track';
 import {addDebugSliceTrack, PluginContextTrace} from '../../public';
 import {findCurrentSelection} from '../../frontend/keyboard_event_handler';
 import {time, Time} from '../../base/time';
 import {BigintMath} from '../../base/bigint_math';
 import {reveal} from '../../frontend/scroll_helper';
 
-// Common TrackType for tracks when using registerStatic or addDebug
-// TODO: b/349502258 - to be removed after single refactoring to single API
-export type TrackType = 'static' | 'debug';
-
 /**
  * Adds debug tracks from SimpleSliceTrackConfig
  * Static tracks cannot be added on command
@@ -51,56 +44,19 @@
 }
 
 /**
- * Registers and pins tracks on traceload, given params
- * TODO: b/349502258 - Refactor to single API
- *
- * @param {PluginContextTrace} ctx Context for trace methods and properties
- * @param {SimpleSliceTrackConfig} config Track config to add
- * @param {string} trackName Track name to display
- * @param {string} uri Unique identifier for the track
- */
-export function addDebugTrackOnTraceLoad(
-  ctx: PluginContextTrace,
-  config: SimpleSliceTrackConfig,
-  trackName: string,
-  uri: string,
-) {
-  ctx.registerStaticTrack({
-    uri: uri,
-    title: trackName,
-    isPinned: true,
-    trackFactory: (trackCtx) => {
-      return new SimpleSliceTrack(ctx.engine, trackCtx, config);
-    },
-  });
-}
-
-/**
  * Registers and pins tracks on traceload or command
- * Every enabled plugins' onTraceload is executed when the trace is first loaded
- * To add and pin tracks on traceload, need to use registerStaticTrack
- * After traceload, if plugin registered command invocated, then addDebugSliceTrack
- * TODO: b/349502258 - Refactor to single API
  *
  * @param {PluginContextTrace} ctx Context for trace methods and properties
  * @param {SimpleSliceTrackConfig} config Track config to add
  * @param {string} trackName Track name to display
- * @param {TrackType} type Whether to registerStaticTrack or addDebugSliceTrack
  * type 'static' expects caller to pass uri string
- * @param {string} uri Unique track identifier expected when type is 'static'
  */
 export function addAndPinSliceTrack(
   ctx: PluginContextTrace,
   config: SimpleSliceTrackConfig,
   trackName: string,
-  type: TrackType,
-  uri?: string,
 ) {
-  if (type == 'static') {
-    addDebugTrackOnTraceLoad(ctx, config, trackName, uri ?? '');
-  } else if (type == 'debug') {
-    addDebugTrackOnCommand(ctx, config, trackName);
-  }
+  addDebugTrackOnCommand(ctx, config, trackName);
 }
 
 /**
@@ -182,20 +138,3 @@
   }
   reveal(trackKey, sliceStart, Time.add(sliceStart, sliceDur), true);
 }
-
-/**
- * Function to check keep checking for object values at set intervals
- *
- * @param {T | undefined} getValue Function to retrieve object value
- * @returns {T} Value returned by getValue when available
- */
-export async function waitForValue<T>(getValue: () => T): Promise<T> {
-  while (true) {
-    // TODO: b/353466921 - update when waiForTraceLoad function added
-    const value = getValue();
-    if (value !== undefined) {
-      return value;
-    }
-    await new Promise((resolve) => setTimeout(resolve, 100));
-  }
-}
diff --git a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts
index afe75a9..6e76fd1 100644
--- a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts
+++ b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts
@@ -19,12 +19,8 @@
   MetricHandler,
 } from './metricUtils';
 import {PluginContextTrace} from '../../../public';
-import {
-  addAndPinSliceTrack,
-  TrackType,
-} from '../../dev.perfetto.AndroidCujs/trackUtils';
+import {addAndPinSliceTrack} from '../../dev.perfetto.AndroidCujs/trackUtils';
 import {SimpleSliceTrackConfig} from '../../../frontend/simple_slice_track';
-import {PLUGIN_ID} from '../pluginId';
 
 class FullTraceJankMetricHandler implements MetricHandler {
   /**
@@ -49,29 +45,23 @@
 
   /**
    * Adds the debug track for full trace jank metrics
-   * The track contains missed sf/app frames for the process
-   * registerStaticTrack used when plugin adds tracks onTraceload()
-   * addDebugSliceTrack used for adding tracks using the command
    *
    * @param {FullTraceMetricData} metricData Parsed metric data for the full trace jank
    * @param {PluginContextTrace} ctx PluginContextTrace for trace related properties and methods
-   * @param {TrackType} type 'static' for onTraceload and 'debug' for command
    * @returns {void} Adds one track for Jank slice
    */
   public async addMetricTrack(
     metricData: FullTraceMetricData,
     ctx: PluginContextTrace,
-    type: TrackType,
   ) {
     const INCLUDE_PREQUERY = `
     INCLUDE PERFETTO MODULE android.frames.jank_type;
     INCLUDE PERFETTO MODULE slices.slices;
     `;
-    const uri = `${PLUGIN_ID}#FullTraceJank#${metricData}`;
     const {config: fullTraceJankConfig, trackName: trackName} =
       this.fullTraceJankConfig(metricData);
     await ctx.engine.query(INCLUDE_PREQUERY);
-    addAndPinSliceTrack(ctx, fullTraceJankConfig, trackName, type, uri);
+    addAndPinSliceTrack(ctx, fullTraceJankConfig, trackName);
   }
 
   private fullTraceJankConfig(metricData: FullTraceMetricData): {
diff --git a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/metricUtils.ts b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/metricUtils.ts
index e1fc2d8..f76645f 100644
--- a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/metricUtils.ts
+++ b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/metricUtils.ts
@@ -11,8 +11,6 @@
 // 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.
-
-import {TrackType} from '../../dev.perfetto.AndroidCujs/trackUtils';
 import {PluginContextTrace} from '../../../public';
 
 /**
@@ -93,15 +91,9 @@
    *
    * @param {MetricData} metricData The parsed metric data.
    * @param {PluginContextTrace} ctx context for trace methods and properties
-   * @param {TrackType} type 'static' onTraceload, 'debug' on command.
-   * TODO: b/349502258 - Refactor to single API
    * @returns {void}
    */
-  addMetricTrack(
-    metricData: MetricData,
-    ctx: PluginContextTrace,
-    type: TrackType,
-  ): void;
+  addMetricTrack(metricData: MetricData, ctx: PluginContextTrace): void;
 }
 
 // Pair for matching metric and its handler
diff --git a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts
index f445915..50b0495 100644
--- a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts
+++ b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts
@@ -18,13 +18,9 @@
   MetricHandler,
 } from './metricUtils';
 import {PluginContextTrace} from '../../../public';
-import {PLUGIN_ID} from '../pluginId';
 import {SimpleSliceTrackConfig} from '../../../frontend/simple_slice_track';
 import {addJankCUJDebugTrack} from '../../dev.perfetto.AndroidCujs';
-import {
-  addAndPinSliceTrack,
-  TrackType,
-} from '../../dev.perfetto.AndroidCujs/trackUtils';
+import {addAndPinSliceTrack} from '../../dev.perfetto.AndroidCujs/trackUtils';
 
 class BlockingCallMetricHandler implements MetricHandler {
   /**
@@ -51,35 +47,27 @@
 
   /**
    * Adds the debug tracks for Blocking Call metrics
-   * registerStaticTrack used when plugin adds tracks onTraceload()
-   * addDebugSliceTrack used for adding tracks using the command
    *
    * @param {BlockingCallMetricData} metricData Parsed metric data for the cuj scoped jank
    * @param {PluginContextTrace} ctx PluginContextTrace for trace related properties and methods
-   * @param {TrackType} type 'static' when called onTraceload and 'debug' when called through command
    * @returns {void} Adds one track for Jank CUJ slice and one for Janky CUJ frames
    */
   public addMetricTrack(
     metricData: BlockingCallMetricData,
     ctx: PluginContextTrace,
-    type: TrackType,
   ): void {
-    this.pinSingleCuj(ctx, metricData, type);
-    const uri = `${PLUGIN_ID}#BlockingCallSlices#${metricData}`;
-    // TODO: b/349502258 - Refactor to single API
+    this.pinSingleCuj(ctx, metricData);
     const {config: blockingCallMetricConfig, trackName: trackName} =
       this.blockingCallTrackConfig(metricData);
-    addAndPinSliceTrack(ctx, blockingCallMetricConfig, trackName, type, uri);
+    addAndPinSliceTrack(ctx, blockingCallMetricConfig, trackName);
   }
 
   private pinSingleCuj(
     ctx: PluginContextTrace,
     metricData: BlockingCallMetricData,
-    type: TrackType,
   ) {
-    const uri = `${PLUGIN_ID}#BlockingCallCUJ#${metricData}`;
     const trackName = `Jank CUJ: ${metricData.cujName}`;
-    addJankCUJDebugTrack(ctx, trackName, type, metricData.cujName, uri);
+    addJankCUJDebugTrack(ctx, trackName, metricData.cujName);
   }
 
   private blockingCallTrackConfig(metricData: BlockingCallMetricData): {
diff --git a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts
index 47bee71..76ea0ca 100644
--- a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts
+++ b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts
@@ -15,8 +15,6 @@
 import {CujMetricData, MetricHandler} from './metricUtils';
 import {PluginContextTrace} from '../../../public';
 import {addJankCUJDebugTrack} from '../../dev.perfetto.AndroidCujs';
-import {TrackType} from '../../dev.perfetto.AndroidCujs/trackUtils';
-import {PLUGIN_ID} from '../pluginId';
 
 /** Pins a single CUJ from CUJ scoped metrics. */
 class PinCujMetricHandler implements MetricHandler {
@@ -39,30 +37,21 @@
 
   /**
    * Adds the debug tracks for cuj Scoped jank metrics
-   * registerStaticTrack used when plugin adds tracks onTraceload()
-   * addDebugSliceTrack used for adding tracks using the command
    *
    * @param {CujMetricData} metricData Parsed metric data for the cuj scoped jank
    * @param {PluginContextTrace} ctx PluginContextTrace for trace related properties and methods
-   * @param {TrackType} type 'static' for onTraceload and 'debug' for command
    * @returns {void} Adds one track for Jank CUJ slice and one for Janky CUJ frames
    */
   public async addMetricTrack(
     metricData: CujMetricData,
     ctx: PluginContextTrace,
-    type: TrackType,
   ) {
-    this.pinSingleCuj(ctx, metricData.cujName, type);
+    this.pinSingleCuj(ctx, metricData.cujName);
   }
 
-  private pinSingleCuj(
-    ctx: PluginContextTrace,
-    cujName: string,
-    type: TrackType,
-  ) {
-    const uri = `${PLUGIN_ID}#PinCuj#${cujName}`;
+  private pinSingleCuj(ctx: PluginContextTrace, cujName: string) {
     const trackName = `Jank CUJ: ${cujName}`;
-    addJankCUJDebugTrack(ctx, trackName, type, cujName, uri);
+    addJankCUJDebugTrack(ctx, trackName, cujName);
   }
 }
 
diff --git a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujScoped.ts b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujScoped.ts
index 8c8e58c..a94656e 100644
--- a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujScoped.ts
+++ b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/handlers/pinCujScoped.ts
@@ -25,9 +25,7 @@
   addAndPinSliceTrack,
   focusOnSlice,
   SliceIdentifier,
-  TrackType,
 } from '../../dev.perfetto.AndroidCujs/trackUtils';
-import {PLUGIN_ID} from '../pluginId';
 import {Time} from '../../../base/time';
 
 const ENABLE_FOCUS_ON_FIRST_JANK = true;
@@ -52,31 +50,29 @@
       jankType: match.groups.jankType as JankType,
     };
     return metricData;
+    1;
   }
 
   /**
-   * Adds the debug tracks for cuj Scoped jank metrics
-   * registerStaticTrack used when plugin adds tracks onTraceload()
-   * addDebugSliceTrack used for adding tracks using the command
+   * Adds the debug tracks for cuj Scoped jank metrics.
    *
    * @param {CujScopedMetricData} metricData Parsed metric data for the cuj scoped jank
    * @param {PluginContextTrace} ctx PluginContextTrace for trace related properties and methods
-   * @param {TrackType} type 'static' for onTraceload and 'debug' for command
    * @returns {void} Adds one track for Jank CUJ slice and one for Janky CUJ frames
    */
   public async addMetricTrack(
     metricData: CujScopedMetricData,
     ctx: PluginContextTrace,
-    type: TrackType,
   ) {
     // TODO: b/349502258 - Refactor to single API
-    const {config: cujScopedJankSlice, trackName: trackName} =
-      await this.cujScopedTrackConfig(metricData, ctx);
-    const uri = `${PLUGIN_ID}#CUJScopedJankSlice#${metricData}`;
-
-    addAndPinSliceTrack(ctx, cujScopedJankSlice, trackName, type, uri);
+    const {
+      config: cujScopedJankSlice,
+      trackName: trackName,
+      tableName: tableName,
+    } = await this.cujScopedTrackConfig(metricData, ctx);
+    addAndPinSliceTrack(ctx, cujScopedJankSlice, trackName);
     if (ENABLE_FOCUS_ON_FIRST_JANK) {
-      await this.focusOnFirstJank(ctx);
+      await this.focusOnFirstJank(ctx, tableName);
     }
   }
 
@@ -86,6 +82,7 @@
   ): Promise<{
     config: SimpleSliceTrackConfig;
     trackName: string;
+    tableName: string;
   }> {
     let jankTypeFilter;
     let jankTypeDisplayName = 'all';
@@ -99,8 +96,10 @@
     const cuj = metricData.cujName;
     const processName = metricData.process;
 
+    const tableWithJankyFramesName = `_janky_frames_during_cuj_from_metric_key_${Math.floor(Math.random() * 1_000_000)}`;
+
     const createJankyCujFrameTable = `
-    CREATE OR REPLACE PERFETTO TABLE _janky_frames_during_cuj_from_metric_key AS
+    CREATE OR REPLACE PERFETTO TABLE ${tableWithJankyFramesName} AS
     SELECT
       f.vsync as id,
       f.ts AS ts,
@@ -113,8 +112,8 @@
     await ctx.engine.query(createJankyCujFrameTable);
 
     const jankyFramesDuringCujQuery = `
-    SELECT id, ts, dur 
-    FROM _janky_frames_during_cuj_from_metric_key
+        SELECT id, ts, dur
+        FROM ${tableWithJankyFramesName}
     `;
 
     const cujScopedJankSlice: SimpleSliceTrackConfig = {
@@ -128,19 +127,25 @@
 
     const trackName = jankTypeDisplayName + ' missed frames in ' + processName;
 
-    return {config: cujScopedJankSlice, trackName: trackName};
+    return {
+      config: cujScopedJankSlice,
+      trackName: trackName,
+      tableName: tableWithJankyFramesName,
+    };
   }
 
   private async findFirstJank(
     ctx: PluginContextTrace,
+    tableWithJankyFramesName: string,
   ): Promise<SliceIdentifier | undefined> {
     const queryForFirstJankyFrame = `
-      SELECT slice_id, track_id, ts, dur FROM slice
+        SELECT slice_id, track_id, ts, dur
+        FROM slice
         WHERE type = "actual_frame_timeline_slice"
-        AND name =
-        CAST(
-        (SELECT id FROM _janky_frames_during_cuj_from_metric_key LIMIT 1)
-        AS VARCHAR(20) );
+          AND name =
+              CAST(
+                      (SELECT id FROM ${tableWithJankyFramesName} LIMIT 1)
+                  AS VARCHAR(20));
     `;
     const queryResult = await ctx.engine.query(queryForFirstJankyFrame);
     if (queryResult.numRows() === 0) {
@@ -161,8 +166,11 @@
     return slice;
   }
 
-  private async focusOnFirstJank(ctx: PluginContextTrace) {
-    const slice = await this.findFirstJank(ctx);
+  private async focusOnFirstJank(
+    ctx: PluginContextTrace,
+    tableWithJankyFramesName: string,
+  ) {
+    const slice = await this.findFirstJank(ctx, tableWithJankyFramesName);
     if (slice) {
       focusOnSlice(slice);
     }
diff --git a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/index.ts b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/index.ts
index 478e969..164811d 100644
--- a/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/index.ts
+++ b/ui/src/plugins/dev.perfetto.PinAndroidPerfMetrics/index.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import {Plugin, PluginContextTrace, PluginDescriptor} from '../../public';
-import {TrackType} from '../dev.perfetto.AndroidCujs/trackUtils';
 import {METRIC_HANDLERS} from './handlers/handlerRegistry';
 import {MetricData, MetricHandlerMatch} from './handlers/metricUtils';
 import {PLUGIN_ID} from './pluginId';
@@ -47,19 +46,15 @@
         metric = prompt('Metrics names (separated by comma)', '');
         if (metric === null) return;
         const metricList = metric.split(',');
-        this.callHandlers(metricList, ctx, 'debug');
+        this.callHandlers(metricList, ctx);
       },
     });
     if (this.metrics.length !== 0) {
-      this.callHandlers(this.metrics, ctx, 'debug');
+      this.callHandlers(this.metrics, ctx);
     }
   }
 
-  private async callHandlers(
-    metricsList: string[],
-    ctx: PluginContextTrace,
-    type: TrackType,
-  ) {
+  private async callHandlers(metricsList: string[], ctx: PluginContextTrace) {
     // List of metrics that actually match some handler
     const metricsToShow: MetricHandlerMatch[] =
       this.getMetricsToShow(metricsList);
@@ -70,7 +65,7 @@
 
     await ctx.engine.query(JANK_CUJ_QUERY_PRECONDITIONS);
     for (const {metricData, metricHandler} of metricsToShow) {
-      metricHandler.addMetricTrack(metricData, ctx, type);
+      metricHandler.addMetricTrack(metricData, ctx);
     }
   }