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);
}
}