Skip to content

Commit

Permalink
Merge "ui: Remove 'GENERIC_SLICE' legacy selection" into main
Browse files Browse the repository at this point in the history
  • Loading branch information
stevegolton authored and Gerrit Code Review committed Oct 7, 2024
2 parents e933668 + 9b768b9 commit 7cabfff
Show file tree
Hide file tree
Showing 41 changed files with 521 additions and 1,643 deletions.
2 changes: 1 addition & 1 deletion python/tools/check_ratchet.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from dataclasses import dataclass

EXPECTED_ANY_COUNT = 59
EXPECTED_RUN_METRIC_COUNT = 5
EXPECTED_RUN_METRIC_COUNT = 4

ROOT_DIR = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Expand Down
144 changes: 22 additions & 122 deletions ui/src/core/selection_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@
import {assertTrue, assertUnreachable} from '../base/logging';
import {
Selection,
LegacySelection,
Area,
SelectionOpts,
SelectionManager,
AreaSelectionAggregator,
SqlSelectionResolver,
} from '../public/selection';
import {duration, Time, time, TimeSpan} from '../base/time';
import {
GenericSliceDetailsTabConfig,
GenericSliceDetailsTabConfigBase,
} from '../public/details_panel';
import {TimeSpan} from '../base/time';
import {raf} from './raf_scheduler';
import {exists, Optional} from '../base/utils';
import {TrackManagerImpl} from './track_manager';
Expand All @@ -49,7 +44,6 @@ const INCOMPLETE_SLICE_DURATION = 30_000n;
// requires querying the SQL engine, which is an async operation.
export class SelectionManagerImpl implements SelectionManager {
private _selection: Selection = {kind: 'empty'};
private _selectedDetails?: LegacySelectionDetails;
private _aggregationManager: SelectionAggregationManager;
// Incremented every time _selection changes.
private readonly selectionResolvers = new Array<SqlSelectionResolver>();
Expand Down Expand Up @@ -177,62 +171,10 @@ export class SelectionManagerImpl implements SelectionManager {
});
}

// There is no matching addLegacy as we did not support multi-single
// selection with the legacy selection system.
selectLegacy(legacySelection: LegacySelection, opts?: SelectionOpts): void {
this.setSelection(
{
kind: 'legacy',
legacySelection,
},
opts,
);
}

selectGenericSlice(args: {
id: number;
sqlTableName: string;
start: time;
duration: duration;
trackUri: string;
detailsPanelConfig: {
kind: string;
config: GenericSliceDetailsTabConfigBase;
};
}): void {
const detailsPanelConfig: GenericSliceDetailsTabConfig = {
id: args.id,
...args.detailsPanelConfig.config,
};
this.setSelection({
kind: 'legacy',
legacySelection: {
kind: 'GENERIC_SLICE',
id: args.id,
sqlTableName: args.sqlTableName,
start: args.start,
duration: args.duration,
trackUri: args.trackUri,
detailsPanelConfig: {
kind: args.detailsPanelConfig.kind,
config: detailsPanelConfig,
},
},
});
}

get selection(): Selection {
return this._selection;
}

get legacySelection(): LegacySelection | null {
return toLegacySelection(this._selection);
}

get legacySelectionDetails(): LegacySelectionDetails | undefined {
return this._selectedDetails;
}

registerSqlSelectionResolver(resolver: SqlSelectionResolver): void {
this.selectionResolvers.push(resolver);
}
Expand Down Expand Up @@ -321,19 +263,37 @@ export class SelectionManagerImpl implements SelectionManager {
switch (this.selection.kind) {
case 'track_event':
return this.selection.trackUri;
case 'legacy':
return this.selection.legacySelection.trackUri;
// TODO(stevegolton): Handle scrolling to area and note selections.
default:
return undefined;
}
})();
const range = this.findTimeRangeOfSelection();
const range = this.findFocusRangeOfSelection();
this.scrollHelper.scrollTo({
time: range ? {...range} : undefined,
track: uri ? {uri: uri, expandGroup: true} : undefined,
});
}

// Finds the time range range that we should actually focus on - using dummy
// values for instant and incomplete slices, so we don't end up super zoomed
// in.
private findFocusRangeOfSelection(): Optional<TimeSpan> {
const sel = this.selection;
if (sel.kind === 'track_event') {
// The focus range of slices is different to that of the actual span
if (sel.dur === -1n) {
return TimeSpan.fromTimeAndDuration(sel.ts, INCOMPLETE_SLICE_DURATION);
} else if (sel.dur === 0n) {
return TimeSpan.fromTimeAndDuration(sel.ts, INSTANT_FOCUS_DURATION);
} else {
return TimeSpan.fromTimeAndDuration(sel.ts, sel.dur);
}
} else {
return this.findTimeRangeOfSelection();
}
}

findTimeRangeOfSelection(): Optional<TimeSpan> {
const sel = this.selection;
if (sel.kind === 'area') {
Expand All @@ -358,70 +318,10 @@ export class SelectionManagerImpl implements SelectionManager {
return TimeSpan.fromTimeAndDuration(sel.ts, sel.dur);
}

const legacySel = this.legacySelection;
if (!exists(legacySel)) {
return undefined;
}

if (legacySel.kind === 'GENERIC_SLICE') {
return findTimeRangeOfSlice({
ts: legacySel.start,
dur: legacySel.duration,
});
}

return undefined;
}

get aggregation() {
return this._aggregationManager;
}
}

function toLegacySelection(selection: Selection): LegacySelection | null {
switch (selection.kind) {
case 'area':
case 'track_event':
case 'empty':
case 'note':
return null;
case 'union':
for (const child of selection.selections) {
const result = toLegacySelection(child);
if (result !== null) {
return result;
}
}
return null;
case 'legacy':
return selection.legacySelection;
default:
assertUnreachable(selection);
return null;
}
}

// Returns the start and end points of a slice-like object If slice is instant
// or incomplete, dummy time will be returned which instead.
function findTimeRangeOfSlice(slice: {ts?: time; dur?: duration}): TimeSpan {
if (exists(slice.ts) && exists(slice.dur)) {
if (slice.dur === -1n) {
return TimeSpan.fromTimeAndDuration(slice.ts, INCOMPLETE_SLICE_DURATION);
} else if (slice.dur === 0n) {
return TimeSpan.fromTimeAndDuration(slice.ts, INSTANT_FOCUS_DURATION);
} else {
return TimeSpan.fromTimeAndDuration(slice.ts, slice.dur);
}
} else {
// TODO(primiano): unclear why we dont return undefined here.
return new TimeSpan(Time.INVALID, Time.INVALID);
}
}

export interface LegacySelectionDetails {
ts?: time;
dur?: duration;
// Additional information for sched selection, used to draw the wakeup arrow.
wakeupTs?: time;
wakerCpu?: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {OnSliceClickArgs} from '../../frontend/base_slice_track';
import {GenericSliceDetailsTab} from '../../frontend/generic_slice_details_tab';
import {NAMED_ROW} from '../../frontend/named_slice_track';
import {NUM, STR} from '../../trace_processor/query_result';
import {LONG, NUM, STR} from '../../trace_processor/query_result';
import {Slice} from '../../public/track';
import {
CustomSqlDetailsPanelConfig,
CustomSqlImportConfig,
CustomSqlTableDefConfig,
CustomSqlTableSliceTrack,
} from '../../frontend/tracks/custom_sql_table_slice_track';
import {PageLoadDetailsPanel} from './page_load_details_panel';
import {StartupDetailsPanel} from './startup_details_panel';
import {WebContentInteractionPanel} from './web_content_interaction_details_panel';
import {TrackEventDetails} from '../../public/selection';
import {Duration, Time} from '../../base/time';

export const CRITICAL_USER_INTERACTIONS_KIND =
'org.chromium.CriticalUserInteraction.track';
Expand All @@ -42,28 +38,6 @@ export interface CriticalUserInteractionSlice extends Slice {
type: string;
}

enum CriticalUserInteractionType {
UNKNOWN = 'Unknown',
PAGE_LOAD = 'chrome_page_loads',
STARTUP = 'chrome_startups',
WEB_CONTENT_INTERACTION = 'chrome_web_content_interactions',
}

function convertToCriticalUserInteractionType(
cujType: string,
): CriticalUserInteractionType {
switch (cujType) {
case CriticalUserInteractionType.PAGE_LOAD:
return CriticalUserInteractionType.PAGE_LOAD;
case CriticalUserInteractionType.STARTUP:
return CriticalUserInteractionType.STARTUP;
case CriticalUserInteractionType.WEB_CONTENT_INTERACTION:
return CriticalUserInteractionType.WEB_CONTENT_INTERACTION;
default:
return CriticalUserInteractionType.UNKNOWN;
}
}

export class CriticalUserInteractionTrack extends CustomSqlTableSliceTrack {
static readonly kind = `/critical_user_interactions`;

Expand All @@ -84,64 +58,34 @@ export class CriticalUserInteractionTrack extends CustomSqlTableSliceTrack {
};
}

getDetailsPanel(
args: OnSliceClickArgs<CriticalUserInteractionSlice>,
): CustomSqlDetailsPanelConfig {
let detailsPanel = {
kind: GenericSliceDetailsTab.kind,
config: {
sqlTableName: this.tableName,
title: 'Chrome Interaction',
},
};
async getSelectionDetails(
id: number,
): Promise<TrackEventDetails | undefined> {
const query = `
SELECT
ts,
dur,
type
FROM (${this.getSqlSource()})
WHERE id = ${id}
`;

switch (convertToCriticalUserInteractionType(args.slice.type)) {
case CriticalUserInteractionType.PAGE_LOAD:
detailsPanel = {
kind: PageLoadDetailsPanel.kind,
config: {
sqlTableName: this.tableName,
title: 'Chrome Page Load',
},
};
break;
case CriticalUserInteractionType.STARTUP:
detailsPanel = {
kind: StartupDetailsPanel.kind,
config: {
sqlTableName: this.tableName,
title: 'Chrome Startup',
},
};
break;
case CriticalUserInteractionType.WEB_CONTENT_INTERACTION:
detailsPanel = {
kind: WebContentInteractionPanel.kind,
config: {
sqlTableName: this.tableName,
title: 'Chrome Web Content Interaction',
},
};
break;
default:
break;
const result = await this.engine.query(query);
if (result.numRows() === 0) {
return undefined;
}
return detailsPanel;
}

onSliceClick(args: OnSliceClickArgs<CriticalUserInteractionSlice>) {
const detailsPanelConfig = this.getDetailsPanel(args);
this.trace.selection.selectGenericSlice({
id: args.slice.scopedId,
sqlTableName: this.tableName,
start: args.slice.ts,
duration: args.slice.dur,
trackUri: this.uri,
detailsPanelConfig: {
kind: detailsPanelConfig.kind,
config: detailsPanelConfig.config,
},
const row = result.iter({
ts: LONG,
dur: LONG,
type: STR,
});

return {
ts: Time.fromRaw(row.ts),
dur: Duration.fromRaw(row.dur),
interactionType: row.type,
};
}

getSqlImports(): CustomSqlImportConfig {
Expand Down
Loading

0 comments on commit 7cabfff

Please sign in to comment.