Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions ui/src/components/tracks/debug_tracks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ async function addPivotedSliceTracks(
});

const trackNode = new TrackNode({uri, name, removable: true});
trace.currentWorkspace.pinnedTracksNode.addChildLast(trackNode);
trace.currentWorkspace.addChildLast(trackNode);
trackNode.pin();
}
}

Expand Down Expand Up @@ -295,7 +296,8 @@ function addSingleSliceTrack(
});

const trackNode = new TrackNode({uri, name, removable: true});
trace.currentWorkspace.pinnedTracksNode.addChildLast(trackNode);
trace.currentWorkspace.addChildLast(trackNode);
trackNode.pin();
}

export interface DebugCounterTrackArgs {
Expand Down Expand Up @@ -419,7 +421,8 @@ async function addPivotedCounterTracks(
});

const trackNode = new TrackNode({uri, name, removable: true});
trace.currentWorkspace.pinnedTracksNode.addChildLast(trackNode);
trace.currentWorkspace.addChildLast(trackNode);
trackNode.pin();
}
}

Expand All @@ -435,5 +438,6 @@ function addSingleCounterTrack(
});

const trackNode = new TrackNode({uri, name, removable: true});
trace.currentWorkspace.pinnedTracksNode.addChildLast(trackNode);
trace.currentWorkspace.addChildLast(trackNode);
trackNode.pin();
}
8 changes: 5 additions & 3 deletions ui/src/frontend/timeline_page/timeline_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ class TimelinePage implements m.ClassComponent<TimelinePageAttrs> {
}

private renderPinnedTracks(trace: TraceImpl): m.Children {
if (trace.currentWorkspace.pinnedTracks.length === 0) return null;
const pinnedTracks = trace.currentWorkspace.pinnedTracks;
if (pinnedTracks.length === 0) return null;

return [
m(
Expand All @@ -141,9 +142,10 @@ class TimelinePage implements m.ClassComponent<TimelinePageAttrs> {
},
m(TrackTreeView, {
trace,
rootNode: trace.currentWorkspace.pinnedTracksNode,
canReorderNodes: true,
rootNode: trace.currentWorkspace.tracks,
nodes: pinnedTracks,
scrollToNewTracks: true,
showFullPath: true,
}),
),
m(ResizeHandle, {
Expand Down
15 changes: 14 additions & 1 deletion ui/src/frontend/timeline_page/track_tree_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ export interface TrackTreeViewAttrs {
// purposes if `reorderable` is set to true.
readonly rootNode: TrackNode;

// Optional: An explicit list of nodes to render instead of rootNode.children.
// When provided, these nodes are rendered as top-level tracks. This is used
// for rendering pinned tracks which are references to nodes that live
// elsewhere in the track tree.
readonly nodes?: ReadonlyArray<TrackNode>;

// Additional class names to add to the root level element.
readonly className?: string;

Expand All @@ -149,6 +155,9 @@ export interface TrackTreeViewAttrs {
readonly trackFilter?: (track: TrackNode) => boolean;

readonly filtersApplied?: boolean;

// When true, show the full path as the title for each track.
readonly showFullPath?: boolean;
}

const TRACK_CONTAINER_REF = 'track-container';
Expand Down Expand Up @@ -184,9 +193,12 @@ export class TrackTreeView implements m.ClassComponent<TrackTreeViewAttrs> {
canRemoveNodes,
className,
rootNode,
nodes,
trackFilter,
filtersApplied,
showFullPath,
} = attrs;
const topLevelNodes = nodes ?? rootNode.children;
const renderedTracks = new Array<TrackView>();
let top = 0;

Expand Down Expand Up @@ -271,6 +283,7 @@ export class TrackTreeView implements m.ClassComponent<TrackTreeViewAttrs> {
stickyTop,
depth,
collapsible: !filtersApplied,
showFullPath,
onTrackMouseOver: () => {
this.hoveredTrackNode = node;
},
Expand All @@ -284,7 +297,7 @@ export class TrackTreeView implements m.ClassComponent<TrackTreeViewAttrs> {
return {vnodes, isVisible};
};

const trackVnodes = rootNode.children
const trackVnodes = topLevelNodes
.map((track) => renderTrack(track))
.map(({vnodes}) => vnodes);

Expand Down
4 changes: 3 additions & 1 deletion ui/src/frontend/timeline_page/track_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ export interface TrackViewAttrs {
readonly depth: number;
readonly stickyTop: number;
readonly collapsible: boolean;
// When true, show the full path as the title instead of just the node name.
readonly showFullPath?: boolean;
onTrackMouseOver(): void;
onTrackMouseOut(): void;
}
Expand Down Expand Up @@ -174,7 +176,7 @@ export class TrackView {
TrackShell,
{
id: node.id,
title: node.name,
title: attrs.showFullPath ? node.fullPath.join(' \u203a ') : node.name,
subtitle: node.subtitle,
ref: node.fullPath.join('/'),
heightPx: height,
Expand Down
3 changes: 2 additions & 1 deletion ui/src/plugins/com.android.InputEvents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ export default class AndroidInputEvents implements PerfettoPlugin {
async visualizeOverlaps(ctx: Trace): Promise<void> {
const window = await getTimeSpanOfSelectionOrVisibleWindow(ctx);
const rootNode = await this.createRootTrack(ctx, window);
ctx.defaultWorkspace.pinnedTracksNode.addChildLast(rootNode);
ctx.defaultWorkspace.addChildLast(rootNode);
rootNode.pin();

const processes = await this.getProcesses(ctx, window);
const processTrackPromises: Promise<TrackNode>[] = [];
Expand Down
3 changes: 2 additions & 1 deletion ui/src/plugins/com.android.MemoryViz/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ export default class MemoryViz implements PerfettoPlugin {

for (const track of createdTracks) {
if (track) {
ctx.defaultWorkspace.pinnedTracksNode.addChildLast(track);
ctx.defaultWorkspace.addChildLast(track);
track.pin();
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion ui/src/plugins/com.android.OomAdjScoreViz/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ export default class OomAdjScoreViz implements PerfettoPlugin {
for (const iter = buckets.iter({}); iter.valid(); iter.next()) {
const bucket = iter.get('bucket') as string;
const track = await this.createTracksForBucket(ctx, window, bucket);
ctx.defaultWorkspace.pinnedTracksNode.addChildLast(track);
ctx.defaultWorkspace.addChildLast(track);
track.pin();
}
},
});
Expand Down
40 changes: 12 additions & 28 deletions ui/src/public/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,64 +577,50 @@ export class Workspace {
public readonly id: string;
public userEditable: boolean = true;

// Dummy node to contain the pinned tracks
public readonly pinnedTracksNode = new TrackNode();
private readonly _pinnedTracks = new Set<TrackNode>();
public readonly tracks = new TrackNode();

get pinnedTracks(): ReadonlyArray<TrackNode> {
return this.pinnedTracksNode.children;
return Array.from(this._pinnedTracks);
}

constructor() {
this.id = createSessionUniqueId();
this.pinnedTracksNode._workspace = this;
this.tracks._workspace = this;

// Expanding these nodes makes the logic work
this.pinnedTracksNode.expand();
// Expanding this node makes the logic work
this.tracks.expand();
}

/**
* Reset the entire workspace including the pinned tracks.
*/
clear(): void {
this.pinnedTracksNode.clear();
this._pinnedTracks.clear();
this.tracks.clear();
}

/**
* Adds a track node to this workspace's pinned area.
* Adds a track node to this workspace's pinned area. The node must already
* be part of this workspace's track tree - pinning creates a reference, not
* a clone.
*/
pinTrack(track: TrackNode): void {
// Make a lightweight clone of this track - just the uri and the title.
const cloned = new TrackNode({
uri: track.uri,
name: track.name,
subtitle: track.subtitle,
removable: track.removable,
chips: track.chips,
});
this.pinnedTracksNode.addChildLast(cloned);
this._pinnedTracks.add(track);
}

/**
* Removes a track node from this workspace's pinned area.
*/
unpinTrack(track: TrackNode): void {
const foundNode = this.pinnedTracksNode.children.find(
(t) => t.uri === track.uri,
);
if (foundNode) {
this.pinnedTracksNode.removeChild(foundNode);
}
this._pinnedTracks.delete(track);
}

/**
* Check if this workspace has a pinned track with the same URI as |track|.
* Check if this workspace has a pinned track.
*/
hasPinnedTrack(track: TrackNode): boolean {
return this.pinnedTracksNode.flatTracks.some((p) => p.uri === track.uri);
return this._pinnedTracks.has(track);
}

/**
Expand All @@ -658,9 +644,7 @@ export class Workspace {
* @returns The node or undefined if no such node exists.
*/
getTrackById(id: string): TrackNode | undefined {
return (
this.tracks.getTrackById(id) || this.pinnedTracksNode.getTrackById(id)
);
return this.tracks.getTrackById(id);
}

/**
Expand Down
Loading