1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { SpSystemTrace } from './SpSystemTrace'; 17import { ThreadStruct, ThreadStructOnClick } from '../database/ui-worker/ProcedureWorkerThread'; 18import { TraceRow } from './trace/base/TraceRow'; 19import { JankStruct, JankStructOnClick } from '../database/ui-worker/ProcedureWorkerJank'; 20import { HeapSnapshotStruct, HeapSnapshotStructOnClick } from '../database/ui-worker/ProcedureWorkerHeapSnapshot'; 21import { FuncStruct, funcStructOnClick } from '../database/ui-worker/ProcedureWorkerFunc'; 22import { CpuFreqStruct, CpuFreqStructOnClick } from '../database/ui-worker/ProcedureWorkerFreq'; 23import { ClockStruct, ClockStructOnClick } from '../database/ui-worker/ProcedureWorkerClock'; 24import { DmaFenceStruct, DmaFenceStructOnClick } from '../database/ui-worker/ProcedureWorkerDmaFence'; 25import { SnapshotStruct, SnapshotStructOnClick } from '../database/ui-worker/ProcedureWorkerSnapshot'; 26import { IrqStruct, IrqStructOnClick } from '../database/ui-worker/ProcedureWorkerIrq'; 27import { HeapStruct, HeapStructOnClick } from '../database/ui-worker/ProcedureWorkerHeap'; 28import { JsCpuProfilerStruct, JsCpuProfilerStructOnClick } from '../database/ui-worker/ProcedureWorkerCpuProfiler'; 29import { AppStartupStruct, AppStartupStructOnClick } from '../database/ui-worker/ProcedureWorkerAppStartup'; 30import { AllAppStartupStruct, allAppStartupStructOnClick } from '../database/ui-worker/ProcedureWorkerAllAppStartup'; 31import { SoStruct, SoStructOnClick } from '../database/ui-worker/ProcedureWorkerSoInit'; 32import { FrameAnimationStruct, FrameAnimationStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameAnimation'; 33import { FrameDynamicStruct, FrameDynamicStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameDynamic'; 34import { FrameSpacingStruct, FrameSpacingStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameSpacing'; 35import { SampleStruct, sampleStructOnClick } from '../database/ui-worker/ProcedureWorkerBpftrace'; 36import { SportRuler } from './trace/timer-shaft/SportRuler'; 37import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; 38import { LitSearch } from './trace/search/Search'; 39import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent'; 40import type { SpKeyboard } from './SpKeyboard'; 41import { enableVSync } from './chart/VSync'; 42import { CpuStruct, CpuStructOnClick } from '../database/ui-worker/cpu/ProcedureWorkerCPU'; 43import { ProcessMemStruct } from '../database/ui-worker/ProcedureWorkerMem'; 44import { CpuStateStruct, CpuStateStructOnClick } from '../database/ui-worker/cpu/ProcedureWorkerCpuState'; 45import { 46 CpuFreqLimitsStruct, 47 CpuFreqLimitsStructOnClick 48} from '../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits'; 49import { FlagsConfig } from './SpFlags'; 50import { LitMainMenu } from '../../base-ui/menu/LitMainMenu'; 51import { PerfToolsStructOnClick, PerfToolStruct } from '../database/ui-worker/ProcedureWorkerPerfTool'; 52import { Utils } from './trace/base/Utils'; 53import { BaseStruct } from '../bean/BaseStruct'; 54import { GpuCounterStruct, gpuCounterStructOnClick } from '../database/ui-worker/ProcedureWorkerGpuCounter'; 55import { HangStructOnClick } from '../database/ui-worker/ProcedureWorkerHang'; 56 57function timeoutJudge(sp: SpSystemTrace): number { 58 let timeoutJudge = window.setTimeout((): void => { 59 if (SpSystemTrace.wakeupList.length && CpuStruct.selectCpuStruct) { 60 let checkHandlerKey: boolean = true; 61 let saveSelectCpuStruct: unknown = JSON.parse(sessionStorage.getItem('saveselectcpustruct')!); 62 for (const item of SpSystemTrace.wakeupList) { 63 if (item.ts === CpuStruct.selectCpuStruct.startTime && item.dur === CpuStruct.selectCpuStruct.dur) { 64 checkHandlerKey = false; 65 if (SpSystemTrace.wakeupList[0].schedulingDesc) { 66 //@ts-ignore 67 SpSystemTrace.wakeupList.unshift(saveSelectCpuStruct); 68 } 69 sp.refreshCanvas(true); 70 break; 71 } else if ( 72 //@ts-ignore 73 saveSelectCpuStruct.startTime === CpuStruct.selectCpuStruct.startTime && 74 //@ts-ignore 75 saveSelectCpuStruct.dur === CpuStruct.selectCpuStruct.dur 76 ) { 77 // 如果点击的是第一层,保持唤醒树不变 78 checkHandlerKey = false; 79 sp.refreshCanvas(true); 80 break; 81 } 82 } 83 // 点击线程在唤醒树内 84 if (!checkHandlerKey) { 85 // 查询获取tab表格数据 86 window.publish(window.SmartEvent.UI.WakeupList, SpSystemTrace.wakeupList); 87 } else { 88 // 不在唤醒树内,清空数组 89 sp.wakeupListNull(); 90 sp.refreshCanvas(true); 91 } 92 } else { 93 sp.wakeupListNull(); 94 sp.refreshCanvas(true); 95 } 96 clearTimeout(timeoutJudge); 97 }, 10); 98 return timeoutJudge; 99} 100 101function threadClickHandlerFunc(sp: SpSystemTrace): (e: ThreadStruct) => void { 102 let threadClickHandler = (d: ThreadStruct): void => { 103 sp.observerScrollHeightEnable = false; 104 sp.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true); 105 let cpuRow = sp.queryAllTraceRow<TraceRow<CpuStruct>>( 106 `trace-row[row-id='${Utils.getDistributedRowId(d.cpu)}'][row-type='cpu-data']`, 107 (row) => row.rowId === `${Utils.getDistributedRowId(d.cpu)}` && row.rowType === 'cpu-data' 108 )[0]; 109 if (cpuRow) { 110 sp.currentRow = cpuRow; 111 cpuRow.fixedList = [ 112 { 113 startTime: d.startTime, 114 dur: d.dur, 115 tid: d.tid, 116 id: d.id, 117 processId: d.pid, 118 cpu: d.cpu, 119 argSetID: d.argSetID, 120 }, 121 ]; 122 let findEntry = cpuRow!.fixedList[0]; 123 sp.rechargeCpuData( 124 // @ts-ignore 125 findEntry, // @ts-ignore 126 cpuRow.dataListCache.find((it) => it.startTime > findEntry.startTime) 127 ); 128 if ( 129 // @ts-ignore 130 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || // @ts-ignore 131 findEntry!.startTime! > TraceRow.range!.endNS 132 ) { 133 sp.timerShaftEL?.setRangeNS( 134 // @ts-ignore 135 findEntry!.startTime! - findEntry!.dur! * 2, // @ts-ignore 136 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 137 ); 138 } 139 sp.hoverStructNull().selectStructNull().wakeupListNull(); // @ts-ignore 140 CpuStruct.hoverCpuStruct = findEntry; // @ts-ignore 141 CpuStruct.selectCpuStruct = findEntry; // @ts-ignore 142 sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 143 sp.traceSheetEL?.displayCpuData( 144 CpuStruct.selectCpuStruct!, 145 (wakeUpBean) => { 146 sp.removeLinkLinesByBusinessType('thread'); 147 CpuStruct.wakeupBean = wakeUpBean; 148 sp.refreshCanvas(true); 149 }, 150 cpuClickHandlerFunc(sp) 151 ); 152 } 153 }; 154 return threadClickHandler; 155} 156 157//点击prio箭头刷新canvas 158function prioClickHandlerFunc(sp: SpSystemTrace): (d: unknown) => void { 159 return function (d: unknown): void { 160 // @ts-ignore 161 ThreadStruct.prioCount = d; 162 ThreadStruct.isClickPrio = true; 163 sp.refreshCanvas(true); 164 }; 165} 166 167function scrollToFuncHandlerFunc(sp: SpSystemTrace): Function { 168 let funClickHandle = (funcStruct: unknown): void => { 169 // @ts-ignore 170 if (funcStruct.chainId) { 171 } 172 sp.observerScrollHeightEnable = true; 173 // @ts-ignore 174 sp.moveRangeToCenter(funcStruct.startTs!, funcStruct.dur!); 175 sp.scrollToActFunc(funcStruct, false); 176 }; 177 return funClickHandle; 178} 179 180function jankClickHandlerFunc(sp: SpSystemTrace): Function { 181 let jankClickHandler = (d: unknown): void => { 182 sp.observerScrollHeightEnable = true; 183 let jankRowParent: unknown; 184 //@ts-ignore 185 if (d.rowId === 'actual frameTime') { 186 jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>("trace-row[row-id='frameTime']"); 187 } else { 188 jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>( 189 //@ts-ignore 190 `trace-row[row-type='process'][row-id='${d.pid}']` 191 ); 192 } 193 //@ts-ignore 194 jankRowParent!.expansion = true; 195 let jankRow: unknown; 196 //@ts-ignore 197 jankRowParent.childrenList.forEach((item: TraceRow<JankStruct>) => { 198 //@ts-ignore 199 if (`${item.rowId}` === `${d.rowId}` && `${item.rowType}` === 'janks') { 200 jankRow = item; 201 } 202 }); 203 //@ts-ignore 204 sp.currentRow = jankRow; 205 if (jankRow) { 206 JankStruct.selectJankStructList.length = 0; 207 //@ts-ignore 208 let findJankEntry = jankRow!.dataListCache!.find( 209 //@ts-ignore 210 (dat: unknown) => `${dat.name}` === `${d.name}` && `${dat.pid}` === `${d.pid}` 211 ); 212 if (findJankEntry) { 213 if ( 214 findJankEntry!.ts! + findJankEntry!.dur! < TraceRow.range!.startNS || 215 findJankEntry!.ts! > TraceRow.range!.endNS 216 ) { 217 sp.timerShaftEL?.setRangeNS( 218 findJankEntry!.ts! - findJankEntry!.dur! * 2, 219 findJankEntry!.ts! + findJankEntry!.dur! + findJankEntry!.dur! * 2 220 ); 221 } 222 sp.hoverStructNull().selectStructNull().wakeupListNull(); 223 JankStruct.hoverJankStruct = findJankEntry; 224 JankStruct.selectJankStruct = findJankEntry; 225 sp.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted'); 226 sp.traceSheetEL?.displayJankData( 227 JankStruct.selectJankStruct!, 228 (datas) => { 229 sp.removeLinkLinesByBusinessType('janks'); 230 // 绘制跟自己关联的线 231 datas.forEach((data) => { 232 //@ts-ignore 233 let endParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>( // @ts-ignore 234 `trace-row[row-type='process'][row-id='${data.pid}'][folder]` 235 ); 236 sp.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data, true); 237 }); 238 }, 239 jankClickHandler 240 ); 241 } 242 //@ts-ignore 243 sp.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, true); 244 } 245 }; 246 return jankClickHandler; 247} 248 249function snapshotClickHandlerFunc(sp: SpSystemTrace): Function { 250 let snapshotClickHandler = (d: HeapSnapshotStruct): void => { 251 sp.observerScrollHeightEnable = true; 252 let snapshotRow = sp.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>(`trace-row[row-id='heapsnapshot']`); 253 let task = (): void => { 254 if (snapshotRow) { 255 let findEntry = snapshotRow!.dataListCache!.find((dat) => dat.startTs === d.startTs); 256 sp.hoverStructNull(); 257 sp.selectStructNull(); 258 sp.wakeupListNull(); 259 HeapSnapshotStruct.hoverSnapshotStruct = findEntry; 260 HeapSnapshotStruct.selectSnapshotStruct = findEntry; 261 } 262 }; 263 if (snapshotRow) { 264 if (snapshotRow!.isComplete) { 265 task(); 266 } else { 267 snapshotRow!.onComplete = task; 268 } 269 } 270 }; 271 return snapshotClickHandler; 272} 273 274//@ts-ignore 275function cpuClickHandlerTask(threadRow: TraceRow<unknown>, sp: SpSystemTrace, d: CpuStruct): void { 276 if (threadRow) { 277 let findEntry = threadRow!.fixedList[0]; 278 if ( 279 //@ts-ignore 280 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || 281 //@ts-ignore 282 findEntry!.startTime! > TraceRow.range!.endNS 283 ) { 284 sp.timerShaftEL?.setRangeNS( 285 //@ts-ignore 286 findEntry!.startTime! - findEntry!.dur! * 2, 287 //@ts-ignore 288 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 289 ); 290 } 291 ThreadStruct.firstselectThreadStruct = ThreadStruct.selectThreadStruct; 292 sp.hoverStructNull().selectStructNull().wakeupListNull(); 293 //@ts-ignore 294 ThreadStruct.hoverThreadStruct = findEntry; 295 //@ts-ignore 296 ThreadStruct.selectThreadStruct = findEntry; 297 //@ts-ignore 298 sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 299 sp.traceSheetEL?.displayThreadData( 300 ThreadStruct.selectThreadStruct!, 301 threadClickHandlerFunc(sp), // @ts-ignore 302 cpuClickHandlerFunc(sp), 303 prioClickHandlerFunc(sp), 304 (datas, str): void => { 305 sp.removeLinkLinesByBusinessType('thread'); 306 if (str === 'wakeup tid') { 307 datas.forEach((data) => { 308 //@ts-ignore 309 let endParentRow = sp.shadowRoot?.querySelector<TraceRow<unknown>>( //@ts-ignore 310 `trace-row[row-id='${data.pid}'][folder]` 311 ); 312 sp.drawThreadLine(endParentRow, ThreadStruct.firstselectThreadStruct, data); 313 }); 314 } 315 sp.refreshCanvas(true); 316 } 317 ); 318 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 319 } 320} 321 322function cpuClickHandlerFunc(sp: SpSystemTrace) { 323 return function (d: CpuStruct): void { 324 //@ts-ignore 325 let traceRow = sp.shadowRoot?.querySelector<TraceRow<unknown>>( 326 `trace-row[row-id='${Utils.getDistributedRowId(d.processId)}'][row-type='process']` 327 ); 328 if (traceRow) { 329 traceRow.expansion = true; 330 } 331 sp.observerScrollHeightEnable = true; 332 let threadRow = sp.queryAllTraceRow<TraceRow<ThreadStruct>>( 333 `trace-row[row-id='${Utils.getDistributedRowId(d.tid)}'][row-type='thread']`, 334 (row) => row.rowId === `${d.tid}` && row.rowType === 'thread' 335 )[0]; 336 sp.currentRow = threadRow; 337 if (threadRow) { 338 threadRow.fixedList = [ 339 { 340 startTime: d.startTime, 341 dur: d.dur, 342 cpu: d.cpu, 343 id: d.id, 344 tid: d.tid, 345 state: d.state, 346 pid: d.processId, 347 argSetID: d.argSetID, 348 }, 349 ]; 350 if (threadRow!.isComplete) { 351 cpuClickHandlerTask(threadRow, sp, d); 352 } else { 353 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'process', false); 354 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 355 threadRow!.onComplete = (): void => cpuClickHandlerTask(threadRow, sp, d); 356 } 357 } 358 }; 359} 360 361 362function allStructOnClick(clickRowType: string, sp: SpSystemTrace, row?: TraceRow<BaseStruct>, entry?: unknown): void { 363 CpuStructOnClick(clickRowType, sp, cpuClickHandlerFunc(sp), entry as CpuStruct) 364 .then(() => ThreadStructOnClick(clickRowType, sp, threadClickHandlerFunc(sp), cpuClickHandlerFunc(sp), 365 prioClickHandlerFunc(sp), entry as ThreadStruct)) 366 .then(() => funcStructOnClick(clickRowType, sp, row as TraceRow<FuncStruct>, 367 scrollToFuncHandlerFunc(sp), entry as FuncStruct)) 368 .then(() => CpuFreqStructOnClick(clickRowType, sp, entry as CpuFreqStruct)) 369 .then(() => CpuStateStructOnClick(clickRowType, sp, entry as CpuStateStruct)) 370 .then(() => CpuFreqLimitsStructOnClick(clickRowType, sp, entry as CpuFreqLimitsStruct)) 371 .then(() => ClockStructOnClick(clickRowType, sp, entry as ClockStruct)) 372 .then(() => HangStructOnClick(clickRowType, sp)) 373 .then(() => DmaFenceStructOnClick(clickRowType, sp, entry as DmaFenceStruct)) 374 .then(() => SnapshotStructOnClick(clickRowType, sp, row as TraceRow<SnapshotStruct>, entry as SnapshotStruct)) 375 .then(() => IrqStructOnClick(clickRowType, sp, entry as IrqStruct)) 376 .then(() => HeapStructOnClick(clickRowType, sp, row as TraceRow<HeapStruct>, entry as HeapStruct)) 377 .then(() => JankStructOnClick(clickRowType, sp, row as TraceRow<JankStruct>, 378 jankClickHandlerFunc(sp), entry as JankStruct)) 379 .then(() => HeapSnapshotStructOnClick(clickRowType, sp, row as TraceRow<HeapSnapshotStruct>, 380 snapshotClickHandlerFunc(sp), entry as HeapSnapshotStruct)) 381 .then(() => JsCpuProfilerStructOnClick(clickRowType, sp, row as TraceRow<JsCpuProfilerStruct>, 382 entry as JsCpuProfilerStruct)) 383 .then(() => AppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as AppStartupStruct)) 384 .then(() => allAppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as AllAppStartupStruct)) 385 .then(() => SoStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as SoStruct)) 386 .then(() => FrameAnimationStructOnClick(clickRowType, sp, 387 scrollToFuncHandlerFunc(sp), row as TraceRow<FrameAnimationStruct>, entry as FrameAnimationStruct)) 388 .then(() => FrameDynamicStructOnClick(clickRowType, sp, row, entry as FrameDynamicStruct)) 389 .then(() => FrameSpacingStructOnClick(clickRowType, sp, row!, entry as FrameSpacingStruct)) 390 .then(() => sampleStructOnClick(clickRowType, sp, row as TraceRow<SampleStruct>, entry as SampleStruct)) 391 .then(() => gpuCounterStructOnClick(clickRowType, sp, entry as GpuCounterStruct)) 392 .then(() => PerfToolsStructOnClick(clickRowType, sp, entry as PerfToolStruct)) 393 .then(() => { 394 if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) { 395 sp.removeLinkLinesByBusinessType('janks'); 396 } 397 sp.observerScrollHeightEnable = false; 398 sp.selectFlag = null; 399 sp.timerShaftEL?.removeTriangle('inverted'); 400 if (!SportRuler.isMouseInSportRuler) { 401 sp.traceSheetEL?.setMode('hidden'); 402 sp.refreshCanvas(true, 'click'); 403 } 404 }) 405 .catch((e): void => { }); 406} 407export default function spSystemTraceOnClickHandler( 408 sp: SpSystemTrace, 409 clickRowType: string, 410 row?: TraceRow<BaseStruct>, 411 entry?: unknown 412): void { 413 if (row) { 414 sp.currentRow = row; 415 sp.setAttribute('clickRow', clickRowType); 416 sp.setAttribute('rowName', row.name!); 417 sp.setAttribute('rowId', row.rowId!); 418 } 419 if (!sp.loadTraceCompleted) { 420 return; 421 } 422 sp.queryAllTraceRow().forEach((it): boolean => (it.rangeSelect = false)); 423 sp.selectStructNull(); 424 // 判断点击的线程是否在唤醒树内 425 timeoutJudge(sp); 426 allStructOnClick(clickRowType, sp, row, entry); 427 if (!JankStruct.selectJankStruct) { 428 sp.removeLinkLinesByBusinessType('janks'); 429 } 430 if (!ThreadStruct.selectThreadStruct) { 431 sp.removeLinkLinesByBusinessType('thread'); 432 } 433 if (!FuncStruct.selectFuncStruct) { 434 sp.removeLinkLinesByBusinessType('distributed', 'func'); 435 } 436 if (row) { 437 let pointEvent = sp.createPointEvent(row); 438 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 439 action: 'trace_row', // @ts-ignore 440 event: pointEvent, 441 }); 442 } 443} 444 445//@ts-ignore 446function handleActions(sp: SpSystemTrace, rows: Array<TraceRow<unknown>>, ev: MouseEvent): void { 447 if (sp.rangeSelect.isMouseDown && sp.rangeSelect.drag) { 448 let downRow = sp.visibleRows.find((row) => row.containPoint(ev)); 449 if (downRow && downRow.traceId !== Utils.currentSelectTrace) { 450 spSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev); 451 return; 452 } 453 } 454 sp.rangeSelect.mouseMove(rows, ev); 455 if (sp.rangeSelect.rangeTraceRow!.length > 0) { 456 sp.tabCpuFreq!.rangeTraceRow = sp.rangeSelect.rangeTraceRow; 457 sp.tabCpuState!.rangeTraceRow = sp.rangeSelect.rangeTraceRow; 458 } 459 let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search'); 460 if (sp.rangeSelect.isMouseDown && search?.isClearValue) { 461 spSystemTraceDocumentOnMouseMoveMouseDown(sp, search); 462 } else { 463 spSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev); 464 } 465} 466 467function handleMouseInTimeShaft(sp: SpSystemTrace, ev: MouseEvent): boolean | undefined { 468 let isMouseInTimeShaft = sp.timerShaftEL?.containPoint(ev); 469 if (isMouseInTimeShaft) { 470 sp.tipEL!.style.display = 'none'; 471 sp.hoverStructNull(); 472 } 473 return isMouseInTimeShaft; 474} 475 476export function spSystemTraceDocumentOnMouseMove(sp: SpSystemTrace, ev: MouseEvent): void { 477 //@ts-ignore 478 if (!sp.loadTraceCompleted || (window as unknown).flagInputFocus || !sp.mouseEventEnable) { 479 return; 480 } 481 //@ts-ignore 482 if ((window as unknown).collectResize) { 483 sp.style.cursor = 'row-resize'; 484 sp.cancelDrag(); 485 return; 486 } 487 if (sp.isWASDKeyPress()) { 488 sp.hoverFlag = null; 489 ev.preventDefault(); 490 return; 491 } 492 if (ev.ctrlKey && ev.button === 0 && SpSystemTrace.isMouseLeftDown) { 493 // 计算当前tab组件的高度 494 let tabHeight: number = 495 sp.shadowRoot?.querySelector('trace-sheet')!.shadowRoot?.querySelector('lit-tabs')!.clientHeight! + 1; 496 // 计算当前屏幕内高与鼠标位置坐标高度的差值 497 let diffHeight: number = window.innerHeight - ev.clientY; 498 // 如果差值大于面板高度,意味着鼠标位于泳道区域,可以通过ctrl+鼠标左键移动。否则不予生效 499 if (diffHeight > tabHeight) { 500 sp.translateByMouseMove(ev); 501 } else { 502 // 若鼠标位于tab面板区,则将其中标志位置成false 503 SpSystemTrace.isMouseLeftDown = false; 504 } 505 } 506 sp.inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev); 507 //@ts-ignore 508 if ((window as unknown).isSheetMove || sp.isMouseInSheet(ev)) { 509 sp.hoverStructNull(); 510 sp.tipEL!.style.display = 'none'; 511 return; 512 } 513 let isMouseInTimeShaft = handleMouseInTimeShaft(sp, ev); 514 let rows = sp.visibleRows; 515 sp.timerShaftEL?.documentOnMouseMove(ev, sp); 516 517 if (isMouseInTimeShaft) { 518 return; 519 } 520 handleActions(sp, rows, ev); 521} 522 523function spSystemTraceDocumentOnMouseMoveMouseDown(sp: SpSystemTrace, search: LitSearch): void { 524 sp.refreshCanvas(true, 'sp move down'); 525 if (TraceRow.rangeSelectObject) { 526 if (search && search.searchValue !== '') { 527 search.clear(); 528 search.valueChangeHandler?.(''); 529 } 530 } 531} 532 533function spSystemTraceDocumentOnMouseMoveMouseUp( 534 sp: SpSystemTrace, //@ts-ignore 535 rows: Array<TraceRow<unknown>>, 536 ev: MouseEvent 537): void { 538 if (!sp.rowsPaneEL!.containPoint(ev, { left: 248 })) { 539 sp.hoverStructNull(); 540 } 541 const transformYMatch = sp.canvasPanel?.style.transform.match(/\((\d+)[^\)]+\)/); 542 const transformY = transformYMatch![1]; 543 let favoriteHeight = sp.favoriteChartListEL!.getBoundingClientRect().height; 544 // @ts-ignore 545 let memTr = rows.filter((item: unknown) => item.rowType === TraceRow.ROW_TYPE_MEM); 546 rows 547 .filter((it) => it.focusContain(ev, sp.inFavoriteArea!, Number(transformY), favoriteHeight) && it.collect === sp.inFavoriteArea) 548 .filter((it) => { 549 if (it.collect) { 550 return true; 551 } else { 552 return ( 553 it.getBoundingClientRect().bottom + it.getBoundingClientRect().height > 554 sp.favoriteChartListEL!.getBoundingClientRect().bottom 555 ); 556 } 557 }) 558 .forEach((tr): void => { 559 if (tr.rowType !== TraceRow.ROW_TYPE_CPU) { 560 CpuStruct.hoverCpuStruct = undefined; 561 } 562 if (tr.rowType !== TraceRow.ROW_TYPE_MEM) { 563 ProcessMemStruct.hoverProcessMemStruct = undefined; 564 memTr.forEach((i: unknown) => { 565 // @ts-ignore 566 i.focusHandler(ev); 567 }); 568 } 569 if (sp.currentRowType !== tr.rowType) { 570 sp.currentRowType = tr.rowType || ''; 571 } 572 tr.findHoverStruct?.(); 573 tr.focusHandler?.(ev); 574 }); 575 requestAnimationFrame(() => sp.refreshCanvas(true, 'sp move up')); 576} 577 578export function spSystemTraceDocumentOnMouseOut(sp: SpSystemTrace, ev: MouseEvent): void { 579 if (!sp.loadTraceCompleted) { 580 return; 581 } 582 CpuStruct.hoverCpuStruct = undefined; 583 TraceRow.isUserInteraction = false; 584 SpSystemTrace.isMouseLeftDown = false; 585 if (sp.isMouseInSheet(ev)) { 586 return; 587 } 588 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 589 sp.rangeSelect.mouseOut(ev); 590 sp.timerShaftEL?.documentOnMouseOut(ev); 591 } 592} 593 594export function spSystemTraceDocumentOnKeyPress(this: unknown, sp: SpSystemTrace, ev: KeyboardEvent): void { 595 SpSystemTrace.isKeyUp = false; 596 if (!sp.loadTraceCompleted) { 597 return; 598 } 599 let keyPress = ev.key.toLocaleLowerCase(); 600 TraceRow.isUserInteraction = true; 601 if (sp.isMousePointInSheet) { 602 return; 603 } 604 sp.observerScrollHeightEnable = false; 605 if (sp.keyboardEnable) { 606 if (keyPress === 'm') { 607 sp.slicestime = sp.setSLiceMark(ev.shiftKey); 608 if (sp.slicestime) { 609 if (TraceRow.rangeSelectObject) { 610 let showTab = sp.getShowTab(); 611 sp.traceSheetEL 612 ?.displayTab<TabPaneCurrent>('tabpane-current', ...showTab) 613 .setCurrentSlicesTime(sp.slicestime); 614 } else { 615 sp.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current').setCurrentSlicesTime(sp.slicestime); 616 } 617 } 618 } 619 if (keyPress === 'f') { 620 let isSelectSliceOrFlag = false; 621 // 设置当前选中的slicetime 622 let selectSlice: unknown = undefined; 623 sp._slicesList.forEach((slice: { selected: boolean }): void => { 624 if (slice.selected) { 625 selectSlice = slice; 626 } 627 }); 628 if (!!selectSlice) { 629 //@ts-ignore 630 sp.currentSlicesTime.startTime = selectSlice.startTime; 631 //@ts-ignore 632 sp.currentSlicesTime.endTime = selectSlice.endTime; 633 isSelectSliceOrFlag = true; 634 } 635 636 if (!!sp.selectFlag) { 637 sp.currentSlicesTime.startTime = sp.selectFlag?.time; 638 sp.currentSlicesTime.endTime = sp.selectFlag?.time; 639 isSelectSliceOrFlag = true; 640 } 641 // 设置当前的slicesTime 642 !isSelectSliceOrFlag && sp.setCurrentSlicesTime(); 643 } 644 let keyPressWASD = keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd'; 645 if (keyPressWASD) { 646 sp.keyPressMap.set(keyPress, true); 647 if (sp.rangeSelect.isMouseDown && sp.rangeSelect.drag) { 648 sp.rangeSelect.mouseUp(); 649 } 650 sp.hoverFlag = null; 651 } 652 sp.timerShaftEL!.documentOnKeyPress(ev, sp.currentSlicesTime); 653 if (keyPress === 'f') { 654 sp.verticalScrollToRow(); 655 } 656 } else { 657 sp.stopWASD(); 658 } 659} 660 661export function spSystemTraceDocumentOnMouseDown(sp: SpSystemTrace, ev: MouseEvent): void { 662 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 663 return; 664 } 665 if (sp.isWASDKeyPress()) { 666 ev.preventDefault(); 667 ev.stopPropagation(); 668 return; 669 } 670 if (ev.button === 0) { 671 SpSystemTrace.isMouseLeftDown = true; 672 if (ev.ctrlKey) { 673 ev.preventDefault(); 674 sp.style.cursor = 'move'; 675 sp.mouseCurrentPosition = ev.clientX; 676 return; 677 } 678 } 679 680 TraceRow.isUserInteraction = true; 681 if (sp.isMouseInSheet(ev)) { 682 return; 683 } 684 sp.observerScrollHeightEnable = false; 685 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 686 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 687 let y = ev.offsetY; 688 sp.timerShaftEL?.documentOnMouseDown(ev); 689 if (y > sp.timerShaftEL!.offsetHeight) { 690 sp.rangeSelect.mouseDown(ev); 691 sp.rangeSelect.drag = true; 692 let downRow = sp.visibleRows.find((row) => row.containPoint(ev)); 693 Utils.currentSelectTrace = downRow?.traceId; 694 } 695 // 如果鼠标摁下事件发生在traceRow范围或时间轴(sportRuler除外)范围内,清除上次点击调用栈产生的所有的三角旗子 696 // ev.offsetY:鼠标在SpSystemTrace元素的y轴偏移量 697 if ( 698 ev.offsetY > sp.timerShaftEL!.clientHeight || 699 ev.offsetY < sp.timerShaftEL!.clientHeight - sp.timerShaftEL!.sportRuler!.frame.height 700 ) { 701 sp.clearTriangle(sp.timerShaftEL!.sportRuler!.flagList); 702 } 703 } else { 704 sp.rangeSelect.drag = false; 705 } 706} 707 708function handleTimerShaftActions(ev: MouseEvent, sp: SpSystemTrace): void { 709 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 710 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 711 let y = ev.offsetY; 712 if ( 713 sp.timerShaftEL!.sportRuler!.frame.contains(x, y) && 714 x > (TraceRow.rangeSelectObject?.startX || 0) && 715 x < (TraceRow.rangeSelectObject?.endX || 0) 716 ) { 717 let findSlicestime = sp.timerShaftEL!.sportRuler?.findSlicesTime(x, y); // 查找帽子 718 if (!findSlicestime) { 719 // 如果没有找到帽子,则绘制一个旗子 720 let time = Math.round( 721 (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / sp.timerShaftEL!.canvas!.offsetWidth + 722 TraceRow.range?.startNS! 723 ); 724 sp.timerShaftEL!.sportRuler!.drawTriangle(time, 'squre'); 725 } 726 } 727 } 728} 729 730export function spSystemTraceDocumentOnMouseUp(sp: SpSystemTrace, ev: MouseEvent): void { 731 //@ts-ignore 732 if ((window as unknown).collectResize) { 733 return; 734 } 735 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 736 return; 737 } 738 if (sp.isWASDKeyPress()) { 739 ev.preventDefault(); 740 ev.stopPropagation(); 741 return; 742 } 743 SpSystemTrace.isMouseLeftDown = false; 744 if (ev.ctrlKey) { 745 ev.preventDefault(); 746 sp.offsetMouse = 0; 747 sp.mouseCurrentPosition = 0; 748 sp.style.cursor = 'default'; 749 return; 750 } 751 TraceRow.isUserInteraction = false; 752 sp.rangeSelect.isMouseDown = false; 753 //@ts-ignore 754 if ((window as unknown).isSheetMove) { 755 return; 756 } 757 if (sp.isMouseInSheet(ev)) { 758 return; 759 } 760 handleTimerShaftActions(ev, sp); 761 if (!SportRuler.isMouseInSportRuler) { 762 sp.rangeSelect.mouseUp(ev); 763 } 764 sp.timerShaftEL?.documentOnMouseUp(ev); 765} 766 767export function spSystemTraceDocumentOnKeyUp(sp: SpSystemTrace, ev: KeyboardEvent): void { 768 SpSystemTrace.isKeyUp = true; 769 if (sp.times.size > 0) { 770 for (let timerId of sp.times) { 771 clearTimeout(timerId); 772 } 773 } 774 let flag: boolean = sp.parentElement 775 ?.querySelector('sp-record-trace')! 776 .shadowRoot?.querySelector('lit-main-menu-item[icon="file-config"]')! 777 .hasAttribute('back')!; 778 if (ev.key.toLocaleLowerCase() === String.fromCharCode(47) && !flag) { 779 if (SpSystemTrace.keyboardFlar) { 780 document 781 .querySelector('body > sp-application')! 782 .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'visible'; 783 SpSystemTrace.keyboardFlar = false; 784 } else { 785 document 786 .querySelector('body > sp-application')! 787 .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'hidden'; 788 SpSystemTrace.keyboardFlar = true; 789 } 790 } 791 if (!sp.loadTraceCompleted) { 792 return; 793 } 794 let flagsItem = window.localStorage.getItem(FlagsConfig.FLAGS_CONFIG_KEY); 795 let flagsItemJson = JSON.parse(flagsItem!); 796 if (flagsItemJson.VSync === 'Enabled') { 797 sp.keyboardEnable && enableVSync(false, ev, () => sp.refreshCanvas(true, 'sp key up')); 798 } 799 let keyPress = ev.key.toLocaleLowerCase(); 800 if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') { 801 sp.keyPressMap.set(keyPress, false); 802 } 803 TraceRow.isUserInteraction = false; 804 sp.observerScrollHeightEnable = false; 805 sp.keyboardEnable && sp.timerShaftEL!.documentOnKeyUp(ev); 806 if (ev.code === 'Enter' || ev.code === 'NumpadEnter') { 807 document.removeEventListener('keydown', sp.documentOnKeyDown); 808 if (ev.shiftKey) { 809 sp.dispatchEvent( 810 new CustomEvent('trace-previous-data', { 811 detail: {}, 812 composed: false, 813 }) 814 ); 815 } else { 816 if (sp.focusTarget === '') { 817 sp.dispatchEvent( 818 new CustomEvent('trace-next-data', { 819 detail: {}, 820 composed: false, 821 }) 822 ); 823 } 824 } 825 document.addEventListener('keydown', sp.documentOnKeyDown); 826 } 827 828 if (ev.ctrlKey) { 829 spSystemTraceDocumentOnKeyUpCtrlKey(keyPress, sp, ev); 830 } 831} 832 833function spSystemTraceDocumentOnKeyUpCtrlKey(keyPress: string, sp: SpSystemTrace, ev: KeyboardEvent): void { 834 if (keyPress === 'b') { 835 let menuBox = document 836 .querySelector('body > sp-application')! 837 .shadowRoot?.querySelector('#main-menu') as LitMainMenu; 838 let searchBox = document 839 .querySelector('body > sp-application') 840 ?.shadowRoot?.querySelector('div > div.search-vessel') as HTMLDivElement; 841 let appContent = document 842 .querySelector('body > sp-application') 843 ?.shadowRoot?.querySelector('div > #app-content') as HTMLDivElement; 844 let rowPane = appContent 845 ?.querySelector('#sp-system-trace') 846 ?.shadowRoot?.querySelector('div > div.rows-pane') as HTMLDivElement; 847 let timerShaft = appContent 848 ?.querySelector('#sp-system-trace') 849 ?.shadowRoot?.querySelector('div > timer-shaft-element') as HTMLDivElement; 850 let spChartList = appContent 851 ?.querySelector('#sp-system-trace') 852 ?.shadowRoot?.querySelector('div > sp-chart-list') as HTMLDivElement; 853 let canvasEle = spChartList.shadowRoot?.querySelector('canvas') as unknown as HTMLDivElement; 854 let sidebarButton = searchBox!.querySelector('div > div.sidebar-button') as HTMLDivElement; 855 let importConfigDiv = searchBox!.querySelector('div > #import-key-path') as HTMLDivElement; 856 if (menuBox.style.zIndex! === '2000' || searchBox!.style.display !== 'none') { 857 SpSystemTrace.isHiddenMenu = true; 858 menuBox.style.width = '0px'; 859 menuBox.style.display = 'flex'; 860 menuBox.style.zIndex = '0'; 861 sidebarButton.style.width = '48px'; 862 importConfigDiv!.style.left = '45px'; 863 searchBox!.style.display = 'none'; 864 rowPane.style.maxHeight = '100%'; 865 } else { 866 SpSystemTrace.isHiddenMenu = false; 867 menuBox.style.width = '248px'; 868 menuBox.style.zIndex = '2000'; 869 menuBox.style.display = 'flex'; 870 sidebarButton.style.width = '0px'; 871 importConfigDiv!.style.left = '5px'; 872 searchBox!.style.display = ''; 873 rowPane.style.maxHeight = '100%'; 874 } 875 } 876 if (keyPress === '[' && sp._slicesList.length > 1) { 877 sp.selectFlag = undefined; 878 sp.MarkJump(sp._slicesList, 'slice', 'previous', ev); 879 } else if (keyPress === ',' && sp._flagList.length > 1) { 880 sp.MarkJump(sp._flagList, 'flag', 'previous', ev); 881 } else if (keyPress === ']' && sp._slicesList.length > 1) { 882 sp.selectFlag = undefined; 883 sp.MarkJump(sp._slicesList, 'slice', 'next', ev); 884 } else if (keyPress === '.' && sp._flagList.length > 1) { 885 sp.MarkJump(sp._flagList, 'flag', 'next', ev); 886 } else { 887 return; 888 } 889} 890 891function handleClickActions(sp: SpSystemTrace, x: number, y: number, ev: MouseEvent): void { 892 if ( 893 !( 894 sp.timerShaftEL!.sportRuler!.frame.contains(x, y) && 895 x > (TraceRow.rangeSelectObject?.startX || 0) && 896 x < (TraceRow.rangeSelectObject?.endX || 0) 897 ) 898 ) { 899 const transformYMatch = sp.canvasPanel?.style.transform.match(/\((\d+)[^\)]+\)/); 900 const transformY = transformYMatch![1]; 901 let inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev); 902 let favoriteHeight = sp.favoriteChartListEL!.getBoundingClientRect().height; 903 let rows = sp.visibleRows.filter((it) => 904 it.focusContain(ev, inFavoriteArea!, Number(transformY), favoriteHeight) && it.collect === inFavoriteArea); 905 if (JankStruct.delJankLineFlag) { 906 sp.removeLinkLinesByBusinessType('janks'); 907 } 908 let strict = true; 909 let offset = false; 910 if ( 911 rows[0] && 912 (rows[0].rowType === TraceRow.ROW_TYPE_FRAME_DYNAMIC || rows[0].rowType === TraceRow.ROW_TYPE_FRAME_SPACING) 913 ) { 914 strict = false; 915 offset = true; 916 } 917 if (rows && rows[0] && (rows[0].getHoverStruct(strict, offset) || 918 (rows[0].rowType === TraceRow.ROW_TYPE_GPU_COUNTER && rows[0].getHoverStruct(false)))) { 919 sp.onClickHandler(rows[0]!.rowType!, rows[0], rows[0].getHoverStruct(strict, offset)); 920 sp.documentOnMouseMove(ev); 921 } else { 922 sp.clickEmptyArea(); 923 } 924 } 925} 926 927export function spSystemTraceDocumentOnClick(sp: SpSystemTrace, ev: MouseEvent): void { 928 if (!sp.loadTraceCompleted) { 929 return; 930 } 931 if (sp.isWASDKeyPress()) { 932 sp.hoverFlag = null; 933 ev.preventDefault(); 934 ev.stopPropagation(); 935 return; 936 } 937 //@ts-ignore 938 if ((window as unknown).isSheetMove) { 939 return; 940 } 941 if (sp.isMouseInSheet(ev)) { 942 return; 943 } 944 //@ts-ignore 945 if ((window as unknown).isPackUpTable) { 946 //@ts-ignore 947 (window as unknown).isPackUpTable = false; 948 return; 949 } 950 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 951 let y = ev.offsetY; 952 if (sp.timerShaftEL?.getRangeRuler()?.frame.contains(x, y)) { 953 sp.clickEmptyArea(); 954 return; 955 } 956 if (sp.rangeSelect.isDrag()) { 957 return; 958 } 959 handleClickActions(sp, x, y, ev); 960 ev.preventDefault(); 961} 962 963export function spSystemTraceDocumentOnKeyDown(sp: SpSystemTrace, ev: KeyboardEvent): void { 964 document.removeEventListener('keyup', sp.documentOnKeyUp); 965 sp.debounce(sp.continueSearch, 250, ev)(); 966 document.addEventListener('keyup', sp.documentOnKeyUp); 967} 968