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 { BaseElement, element } from '../../base-ui/BaseElement.js'; 17import './trace/TimerShaftElement.js'; 18import './trace/base/TraceRow.js'; 19import { 20 queryBySelectAllocationOrReturn, 21 queryBySelectExecute, 22 queryEbpfSamplesCount, 23 querySceneSearchFunc, 24 querySearchFunc, 25 threadPool, 26} from '../database/SqlLite.js'; 27import { RangeSelectStruct, TraceRow } from './trace/base/TraceRow.js'; 28import { TimerShaftElement } from './trace/TimerShaftElement.js'; 29import './trace/base/TraceSheet.js'; 30import { TraceSheet } from './trace/base/TraceSheet.js'; 31import { RangeSelect } from './trace/base/RangeSelect.js'; 32import { SelectionParam } from '../bean/BoxSelection.js'; 33import { procedurePool } from '../database/Procedure.js'; 34import { SpApplication } from '../SpApplication.js'; 35import { Flag } from './trace/timer-shaft/Flag.js'; 36import { SlicesTime, SportRuler } from './trace/timer-shaft/SportRuler.js'; 37import { SpHiPerf } from './chart/SpHiPerf.js'; 38import { SearchSdkBean, SearchThreadProcessBean } from '../bean/SearchFuncBean.js'; 39import { error, info } from '../../log/Log.js'; 40import { 41 drawFlagLineSegment, 42 drawLines, 43 drawLinkLines, 44 drawWakeUp, 45 drawWakeUpList, 46 isFrameContainPoint, 47 LineType, 48 ns2x, 49 ns2xByTimeShaft, 50 PairPoint, 51 Rect, 52} from '../database/ui-worker/ProcedureWorkerCommon.js'; 53import { SpChartManager } from './chart/SpChartManager.js'; 54import { CpuStruct, WakeupBean } from '../database/ui-worker/ProcedureWorkerCPU.js'; 55import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess.js'; 56import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq.js'; 57import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; 58import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread.js'; 59import { func, FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc.js'; 60import { CpuStateStruct } from '../database/ui-worker/ProcedureWorkerCpuState.js'; 61import { HiPerfCpuStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCPU.js'; 62import { HiPerfProcessStruct } from '../database/ui-worker/ProcedureWorkerHiPerfProcess.js'; 63import { HiPerfThreadStruct } from '../database/ui-worker/ProcedureWorkerHiPerfThread.js'; 64import { HiPerfEventStruct } from '../database/ui-worker/ProcedureWorkerHiPerfEvent.js'; 65import { HiPerfReportStruct } from '../database/ui-worker/ProcedureWorkerHiPerfReport.js'; 66import { FpsStruct } from '../database/ui-worker/ProcedureWorkerFPS.js'; 67import { CpuAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerCpuAbility.js'; 68import { DiskAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerDiskIoAbility.js'; 69import { MemoryAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerMemoryAbility.js'; 70import { NetworkAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerNetworkAbility.js'; 71import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock.js'; 72import { Utils } from './trace/base/Utils.js'; 73import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq.js'; 74import { JanksStruct } from '../bean/JanksStruct.js'; 75import { JankStruct } from '../database/ui-worker/ProcedureWorkerJank.js'; 76import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent.js'; 77import { HeapStruct } from '../database/ui-worker/ProcedureWorkerHeap.js'; 78import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js'; 79import { HeapSnapshotStruct } from '../database/ui-worker/ProcedureWorkerHeapSnapshot.js'; 80import { HeapDataInterface } from '../../js-heap/HeapDataInterface.js'; 81import { LitTabs } from '../../base-ui/tabs/lit-tabs.js'; 82import { TraceRowConfig } from './trace/base/TraceRowConfig.js'; 83import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.js'; 84import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup.js'; 85import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit.js'; 86import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames.js'; 87import { FlagsConfig } from './SpFlags.js'; 88import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic.js'; 89import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation.js'; 90import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing.js'; 91import { JsCpuProfilerStruct } from '../database/ui-worker/ProcedureWorkerCpuProfiler.js'; 92import { TabPaneSummary } from './trace/sheet/ark-ts/TabPaneSummary.js'; 93import { JsCpuProfilerChartFrame } from '../bean/JsStruct.js'; 94import { FileInfo } from '../../js-heap/model/UiStruct.js'; 95import { SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot.js'; 96import { setSelectState, intersectData } from './Utils.js'; 97 98function dpr() { 99 return window.devicePixelRatio || 1; 100} 101//节流处理 102function throttle(fn: any, t: number, ev: any): any { 103 let timer: any = null; 104 return function () { 105 if (!timer) { 106 timer = setTimeout(function () { 107 if (ev) { 108 fn(ev); 109 } else { 110 fn(); 111 } 112 timer = null; 113 }, t); 114 } 115 }; 116} 117 118export class CurrentSlicesTime { 119 startTime: number | undefined; 120 endTime: number | undefined; 121} 122 123@element('sp-system-trace') 124export class SpSystemTrace extends BaseElement { 125 static mouseCurrentPosition = 0; 126 static offsetMouse = 0; 127 static moveable = true; 128 static scrollViewWidth = 0; 129 static isCanvasOffScreen = true; 130 static DATA_DICT: Map<number, string> = new Map<number, string>(); 131 static DATA_TASK_POOL_CALLSTACK: Map<number, { id: number; ts: number; dur: number; name: string }> = new Map< 132 number, 133 { id: number; ts: number; dur: number; name: string } 134 >(); 135 static SDK_CONFIG_MAP: any; 136 static sliceRangeMark: any; 137 static wakeupList: Array<WakeupBean> = []; 138 currentSlicesTime: CurrentSlicesTime = new CurrentSlicesTime(); 139 intersectionObserver: IntersectionObserver | undefined; 140 tipEL: HTMLDivElement | undefined | null; 141 rowsEL: HTMLDivElement | undefined | null; 142 rowsPaneEL: HTMLDivElement | undefined | null; 143 spacerEL: HTMLDivElement | undefined | null; 144 favoriteRowsEL: HTMLDivElement | undefined | null; 145 visibleRows: Array<TraceRow<any>> = []; 146 collectRows: Array<TraceRow<any>> = []; 147 currentRow: TraceRow<any> | undefined | null; 148 keyboardEnable = true; 149 mouseEventEnable = true; 150 currentRowType = ''; /*保存当前鼠标所在行的类型*/ 151 observerScrollHeightEnable: boolean = false; 152 observerScrollHeightCallback: Function | undefined; 153 // @ts-ignore 154 observer = new ResizeObserver((entries) => { 155 if (this.observerScrollHeightEnable && this.observerScrollHeightCallback) { 156 this.observerScrollHeightCallback(); 157 } 158 }); 159 static btnTimer: any = null; 160 isMousePointInSheet = false; 161 hoverFlag: Flag | undefined | null = undefined; 162 selectFlag: Flag | undefined | null; 163 slicestime: SlicesTime | undefined | null = null; 164 public timerShaftEL: TimerShaftElement | null | undefined; 165 private traceSheetEL: TraceSheet | undefined | null; 166 private rangeSelect!: RangeSelect; 167 chartManager: SpChartManager | undefined | null; 168 private loadTraceCompleted: boolean = false; 169 private rangeTraceRow: Array<TraceRow<any>> | undefined = []; 170 canvasFavoritePanel: HTMLCanvasElement | null | undefined; //绘制收藏泳道图 171 canvasFavoritePanelCtx: CanvasRenderingContext2D | null | undefined; 172 canvasPanel: HTMLCanvasElement | null | undefined; //绘制取消收藏后泳道图 173 canvasPanelCtx: CanvasRenderingContext2D | undefined | null; 174 linkNodes: PairPoint[][] = []; 175 public currentClickRow: HTMLDivElement | undefined | null; 176 private litTabs: LitTabs | undefined | null; 177 eventMap: any = {}; 178 private isSelectClick: boolean = false; 179 private selectionParam: SelectionParam | undefined; 180 private snapshotFiles: FileInfo | null | undefined; 181 182 set snapshotFile(data: FileInfo) { 183 this.snapshotFiles = data; 184 } 185 186 addPointPair(startPoint: PairPoint, endPoint: PairPoint) { 187 if (startPoint.rowEL.collect) { 188 startPoint.rowEL.translateY = startPoint.rowEL.getBoundingClientRect().top - 195; 189 } else { 190 startPoint.rowEL.translateY = startPoint.rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 191 } 192 if (endPoint.rowEL.collect) { 193 endPoint.rowEL.translateY = endPoint.rowEL.getBoundingClientRect().top - 195; 194 } else { 195 endPoint.rowEL.translateY = endPoint.rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 196 } 197 startPoint.y = startPoint.rowEL!.translateY! + startPoint.offsetY; 198 endPoint.y = endPoint.rowEL!.translateY! + endPoint.offsetY; 199 this.linkNodes.push([startPoint, endPoint]); 200 } 201 202 clearPointPair() { 203 this.linkNodes.length = 0; 204 } 205 206 removeLinkLinesByBusinessType(...businessTypes: string[]) { 207 this.linkNodes = this.linkNodes.filter((pointPair) => { 208 return !(businessTypes.indexOf(pointPair[0].business) > -1); 209 }); 210 } 211 212 hiddenLinkLinesByBusinessType(...businessTypes: string[]) { 213 this.linkNodes.map((value) => { 214 if (businessTypes.indexOf(value[0].business) !== -1) { 215 value[0].hidden = true; 216 value[1].hidden = true; 217 } 218 }); 219 } 220 221 showLinkLinesByBusinessType(...businessTypes: string[]) { 222 this.linkNodes.map((value) => { 223 if (businessTypes.indexOf(value[0].business) !== -1) { 224 value[0].hidden = false; 225 value[1].hidden = false; 226 } 227 }); 228 } 229 230 initElements(): void { 231 let sideColor = 232 document!.querySelector('body > sp-application')?.shadowRoot?.querySelector!( 233 '#main-menu' 234 )?.shadowRoot?.querySelector('div.bottom > div.color'); 235 this.traceSheetEL = this.shadowRoot?.querySelector('.trace-sheet'); 236 let rightButton: HTMLElement | null | undefined = this.traceSheetEL?.shadowRoot 237 ?.querySelector('#current-selection > tabpane-current-selection') 238 ?.shadowRoot?.querySelector('#rightButton'); 239 let rightStar: HTMLElement | null | undefined = this.traceSheetEL?.shadowRoot 240 ?.querySelector('#current-selection > tabpane-current-selection') 241 ?.shadowRoot?.querySelector('#right-star'); 242 this.rowsEL = this.shadowRoot?.querySelector<HTMLDivElement>('.rows'); 243 this.tipEL = this.shadowRoot?.querySelector<HTMLDivElement>('.tip'); 244 this.rowsPaneEL = this.shadowRoot?.querySelector<HTMLDivElement>('.rows-pane'); 245 this.spacerEL = this.shadowRoot?.querySelector<HTMLDivElement>('.spacer'); 246 this.canvasFavoritePanel = this.shadowRoot?.querySelector<HTMLCanvasElement>('.panel-canvas-favorite'); 247 this.timerShaftEL = this.shadowRoot?.querySelector('.timer-shaft'); 248 this.favoriteRowsEL = this.shadowRoot?.querySelector('.favorite-rows'); 249 this.rangeSelect = new RangeSelect(this); 250 rightButton?.addEventListener('click', (event: any) => { 251 if (SpSystemTrace.btnTimer) { 252 return; 253 } 254 this.wakeupListNull(); 255 SpSystemTrace.wakeupList.unshift(CpuStruct.wakeupBean!); 256 this.queryCPUWakeUpList(CpuStruct.wakeupBean!); 257 setTimeout(() => { 258 requestAnimationFrame(() => this.refreshCanvas(false)); 259 }, 300); 260 rightStar!.style.visibility = 'visible'; 261 rightStar!.style.cursor = 'pointer'; 262 SpSystemTrace.btnTimer = setTimeout(() => { 263 SpSystemTrace.btnTimer = null; // 2.清空节流阀,方便下次开启定时器 264 }, 2000); 265 }); 266 rightStar?.addEventListener('click', () => { 267 let wakeupLists = []; 268 for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) { 269 wakeupLists.unshift(CpuStruct.selectCpuStruct?.cpu); 270 wakeupLists.push(SpSystemTrace.wakeupList[i].cpu); 271 } 272 let wakeupCpuLists = Array.from(new Set(wakeupLists)).sort(); 273 for (let i = 0; i < wakeupCpuLists.length; i++) { 274 let cpuFavoriteRow: any = this.shadowRoot?.querySelector<TraceRow<any>>( 275 `trace-row[row-type='cpu-data'][row-id='${wakeupCpuLists[i]}']` 276 ); 277 cpuFavoriteRow!.setAttribute('collect-type', ''); 278 let replaceRow = document.createElement('div'); 279 replaceRow.setAttribute('row-id', cpuFavoriteRow.rowId + '-' + cpuFavoriteRow.rowType); 280 replaceRow.setAttribute('type', 'replaceRow'); 281 replaceRow.setAttribute('row-parent-id', cpuFavoriteRow.rowParentId); 282 replaceRow.style.display = 'none'; 283 cpuFavoriteRow.rowHidden = !cpuFavoriteRow.hasAttribute('scene'); 284 if (this.rowsEL!.contains(cpuFavoriteRow)) { 285 this.rowsEL!.replaceChild(replaceRow, cpuFavoriteRow); 286 } 287 this.favoriteRowsEL!.append(cpuFavoriteRow); 288 this.currentClickRow = null; 289 cpuFavoriteRow.setAttribute('draggable', 'true'); 290 cpuFavoriteRow.addEventListener('dragstart', () => { 291 this.currentClickRow = cpuFavoriteRow; 292 }); 293 cpuFavoriteRow.addEventListener('dragover', (ev: any) => { 294 ev.preventDefault(); 295 ev.dataTransfer.dropEffect = 'move'; 296 }); 297 cpuFavoriteRow.addEventListener('drop', (ev: any) => { 298 if (this.favoriteRowsEL != null && this.currentClickRow != null && this.currentClickRow !== cpuFavoriteRow) { 299 let rect = cpuFavoriteRow.getBoundingClientRect(); 300 if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) { 301 //向上移动 302 this.favoriteRowsEL.insertBefore(this.currentClickRow, cpuFavoriteRow); 303 } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) { 304 //向下移动 305 this.favoriteRowsEL.insertBefore(this.currentClickRow, cpuFavoriteRow.nextSibling); 306 } 307 this.refreshFavoriteCanvas(); 308 } 309 }); 310 cpuFavoriteRow.addEventListener('dragend', () => { 311 this.linkNodes.forEach((itln) => { 312 if (itln[0].rowEL.collect) { 313 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 314 } else { 315 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 316 } 317 if (itln[1].rowEL.collect) { 318 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 319 } else { 320 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 321 } 322 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 323 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 324 }); 325 this.currentClickRow = null; 326 }); 327 } 328 this.refreshFavoriteCanvas(); 329 this.refreshCanvas(true); 330 }); 331 sideColor?.addEventListener('click', (event: any) => { 332 requestAnimationFrame(() => this.refreshCanvas(true)); 333 }); 334 document?.addEventListener('triangle-flag', (event: any) => { 335 let temporaryTime = this.timerShaftEL?.drawTriangle(event.detail.time, event.detail.type); 336 if (event.detail.timeCallback && temporaryTime) event.detail.timeCallback(temporaryTime); 337 }); 338 document?.addEventListener('flag-change', (event: any) => { 339 this.timerShaftEL?.modifyFlagList(event.detail); 340 if (event.detail.hidden) { 341 this.selectFlag = undefined; 342 this.traceSheetEL?.setAttribute('mode', 'hidden'); 343 this.refreshCanvas(true); 344 } 345 }); 346 document?.addEventListener('slices-change', (event: any) => { 347 this.timerShaftEL?.modifySlicesList(event.detail); 348 if (event.detail.hidden) { 349 this.slicestime = null; 350 this.traceSheetEL?.setAttribute('mode', 'hidden'); 351 this.refreshCanvas(true); 352 } 353 }); 354 if (this.timerShaftEL?.collecBtn) { 355 this.timerShaftEL.collecBtn.onclick = () => { 356 if (this.timerShaftEL!.collecBtn!.hasAttribute('close')) { 357 this.timerShaftEL!.collecBtn!.removeAttribute('close'); 358 } else { 359 this.timerShaftEL!.collecBtn!.setAttribute('close', ''); 360 } 361 if (this.collectRows.length > 0) { 362 this.collectRows.forEach((row) => { 363 row?.collectEL?.onclick?.(new MouseEvent('auto-collect', undefined)); 364 }); 365 } 366 }; 367 } 368 document?.addEventListener('collect', (event: any) => { 369 let currentRow = event.detail.row; 370 if (currentRow.collect) { 371 if ( 372 !this.collectRows.find((find) => { 373 return find === currentRow; 374 }) 375 ) { 376 this.collectRows.push(currentRow); 377 } 378 if (event.detail.type !== 'auto-collect' && this.timerShaftEL!.collecBtn!.hasAttribute('close')) { 379 currentRow.collect = false; 380 this.timerShaftEL!.collecBtn!.click(); 381 return; 382 } 383 let replaceRow = document.createElement('div'); 384 replaceRow.setAttribute('row-id', currentRow.rowId + '-' + currentRow.rowType); 385 replaceRow.setAttribute('type', 'replaceRow'); 386 replaceRow.setAttribute('row-parent-id', currentRow.rowParentId); 387 replaceRow.style.display = 'none'; 388 currentRow.rowHidden = !currentRow.hasAttribute('scene'); 389 // 添加收藏时,在线程名前面追加父亲ID 390 let rowParentId = currentRow.rowParentId; 391 if (rowParentId) { 392 let parentRows = this.shadowRoot?.querySelectorAll<TraceRow<any>>(`trace-row[row-id='${rowParentId}']`); 393 parentRows?.forEach((parentRow) => { 394 if ( 395 parentRow?.name && 396 parentRow?.name != currentRow.name && 397 !parentRow.rowType!.startsWith('cpu') && 398 !parentRow.rowType!.startsWith('thread') && 399 !parentRow.rowType!.startsWith('func') 400 ) { 401 currentRow.name += '(' + parentRow.name + ')'; 402 } 403 }); 404 } 405 if (this.rowsEL!.contains(currentRow)) { 406 this.rowsEL!.replaceChild(replaceRow, currentRow); 407 } else { 408 if (currentRow.hasParentRowEl) { 409 let parent = currentRow.parentRowEl; 410 parent!.replaceTraceRow(replaceRow, currentRow); 411 } 412 } 413 this.favoriteRowsEL!.append(currentRow); 414 } else { 415 this.favoriteRowsEL!.removeChild(currentRow); 416 if (event.detail.type !== 'auto-collect') { 417 let rowIndex = this.collectRows.indexOf(currentRow); 418 if (rowIndex !== -1) { 419 this.collectRows.splice(rowIndex, 1); 420 } 421 } 422 let row = currentRow; 423 let allowExpansionRow = []; 424 while (row.hasParentRowEl) { 425 let parent = row.parentRowEl; 426 allowExpansionRow.push(parent); 427 row = parent; 428 } 429 for (let index: number = allowExpansionRow.length - 1; index >= 0; index--) { 430 if (!allowExpansionRow[index]?.expansion && allowExpansionRow[index]?.hasAttribute('scene')) { 431 allowExpansionRow[index].expansion = true; 432 } 433 } 434 allowExpansionRow.length = 0; 435 let replaceRow = this.rowsEL!.querySelector<HTMLCanvasElement>( 436 `div[row-id='${currentRow.rowId}-${currentRow.rowType}']` 437 ); 438 if (replaceRow != null) { 439 // 取消收藏时,删除父亲ID 440 let rowNameArr = currentRow.name.split('('); 441 if (rowNameArr.length > 1) { 442 let tempName = ''; 443 tempName += rowNameArr[0]; 444 currentRow.name = tempName; 445 } else { 446 currentRow.name = rowNameArr[0]; 447 } 448 this.rowsEL!.replaceChild(currentRow, replaceRow); 449 currentRow.style.boxShadow = `0 10px 10px #00000000`; 450 } 451 this.canvasFavoritePanel!.style.transform = `translateY(${ 452 this.favoriteRowsEL!.scrollTop - currentRow.clientHeight 453 }px)`; 454 } 455 this.timerShaftEL?.displayCollect(this.collectRows.length !== 0); 456 this.refreshFavoriteCanvas(); 457 this.refreshCanvas(true); 458 this.linkNodes.forEach((itln) => { 459 if (itln[0].rowEL === currentRow) { 460 if (itln[0].rowEL.collect) { 461 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 462 } else { 463 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 464 } 465 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 466 } else if (itln[1].rowEL === currentRow) { 467 if (itln[1].rowEL.collect) { 468 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 469 } else { 470 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 471 } 472 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 473 } 474 }); 475 // 收藏夹元素拖动排序功能 476 this.currentClickRow = null; 477 currentRow.setAttribute('draggable', 'true'); 478 currentRow.addEventListener('dragstart', () => { 479 this.currentClickRow = currentRow; 480 }); 481 currentRow.addEventListener('dragover', (ev: any) => { 482 ev.preventDefault(); 483 ev.dataTransfer.dropEffect = 'move'; 484 }); 485 currentRow.addEventListener('drop', (ev: any) => { 486 if (this.favoriteRowsEL != null && this.currentClickRow != null && this.currentClickRow !== currentRow) { 487 let rect = currentRow.getBoundingClientRect(); 488 if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) { 489 //向上移动 490 this.favoriteRowsEL.insertBefore(this.currentClickRow, currentRow); 491 } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) { 492 //向下移动 493 this.favoriteRowsEL.insertBefore(this.currentClickRow, currentRow.nextSibling); 494 } 495 this.refreshFavoriteCanvas(); 496 } 497 }); 498 currentRow.addEventListener('dragend', () => { 499 this.linkNodes.forEach((itln) => { 500 if (itln[0].rowEL.collect) { 501 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 502 } else { 503 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 504 } 505 if (itln[1].rowEL.collect) { 506 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 507 } else { 508 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 509 } 510 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 511 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 512 }); 513 this.currentClickRow = null; 514 }); 515 }); 516 SpSystemTrace.scrollViewWidth = this.getScrollWidth(); 517 this.rangeSelect.selectHandler = (rows, refreshCheckBox) => { 518 rows.forEach((item) => { 519 this.setAttribute('clickRow', item.rowType!); 520 this.setAttribute('rowName', item.name); 521 this.setAttribute('rowId', item.rowId!); 522 }); 523 if (rows.length == 0) { 524 this.shadowRoot!.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => { 525 it.checkType = '-1'; 526 if (it.folder) { 527 it.childrenList.forEach((item) => { 528 it.checkType = '-1'; 529 }); 530 } 531 }); 532 this.refreshCanvas(true); 533 this.traceSheetEL?.setAttribute('mode', 'hidden'); 534 return; 535 } 536 if (refreshCheckBox) { 537 if (rows.length > 0) { 538 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((row) => { 539 row.checkType = '0'; 540 if (row.folder) { 541 row.childrenList.forEach((ite) => { 542 ite.checkType = '0'; 543 }); 544 } 545 }); 546 rows.forEach((it) => { 547 it.checkType = '2'; 548 }); 549 } else { 550 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((row) => { 551 row.checkType = '-1'; 552 if (row.folder) { 553 row.childrenList.forEach((it) => { 554 it.checkType = '-1'; 555 }); 556 } 557 }); 558 return; 559 } 560 } 561 if (!this.isSelectClick) { 562 this.rangeTraceRow = []; 563 } 564 let selection = new SelectionParam(); 565 selection.leftNs = TraceRow.rangeSelectObject?.startNS || 0; 566 selection.rightNs = TraceRow.rangeSelectObject?.endNS || 0; 567 selection.recordStartNs = (window as any).recordStartNS; 568 let native_memory = ['All Heap & Anonymous VM', 'All Heap', 'All Anonymous VM']; 569 rows.forEach((it) => { 570 if (it.rowType == TraceRow.ROW_TYPE_CPU) { 571 selection.cpus.push(parseInt(it.rowId!)); 572 info('load CPU traceRow id is : ', it.rowId); 573 } else if (it.rowType == TraceRow.ROW_TYPE_CPU_STATE) { 574 let filterId = parseInt(it.rowId!); 575 if (selection.cpuStateFilterIds.indexOf(filterId) == -1) { 576 selection.cpuStateFilterIds.push(filterId); 577 } 578 } else if (it.rowType == TraceRow.ROW_TYPE_CPU_FREQ) { 579 let filterId = parseInt(it.rowId!); 580 if (selection.cpuFreqFilterIds.indexOf(filterId) == -1) { 581 selection.cpuFreqFilterIds.push(filterId); 582 } 583 } else if (it.rowType == TraceRow.ROW_TYPE_CPU_FREQ_LIMIT) { 584 selection.cpuFreqLimitDatas.push(it.dataList!); 585 } else if (it.rowType == TraceRow.ROW_TYPE_PROCESS) { 586 this.pushPidToSelection(selection, it.rowId!); 587 if (it.getAttribute('hasStartup') === 'true') { 588 selection.startup = true; 589 } 590 if (it.getAttribute('hasStaticInit') === 'true') { 591 selection.staticInit = true; 592 } 593 let processChildRows: Array<TraceRow<any>> = [ 594 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 595 ]; 596 if (!it.expansion) { 597 processChildRows = [...it.childrenList]; 598 } 599 selection.processIds.push(parseInt(it.rowId!)); 600 processChildRows.forEach((th) => { 601 th.rangeSelect = true; 602 th.checkType = '2'; 603 if (th.rowType == TraceRow.ROW_TYPE_THREAD) { 604 selection.threadIds.push(parseInt(th.rowId!)); 605 } else if (th.rowType == TraceRow.ROW_TYPE_FUNC) { 606 if (th.asyncFuncName) { 607 selection.funAsync.push({ 608 name: th.asyncFuncName, 609 pid: th.asyncFuncNamePID || 0, 610 }); 611 } else { 612 selection.funTids.push(parseInt(th.rowId!)); 613 } 614 } else if (th.rowType == TraceRow.ROW_TYPE_MEM) { 615 selection.processTrackIds.push(parseInt(th.rowId!)); 616 } 617 }); 618 info('load process traceRow id is : ', it.rowId); 619 } else if (it.rowType == TraceRow.ROW_TYPE_NATIVE_MEMORY) { 620 let memoryRows: Array<TraceRow<any>> = [ 621 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 622 ]; 623 if (!it.expansion) { 624 memoryRows = [...it.childrenList]; 625 } 626 memoryRows.forEach((th) => { 627 th.rangeSelect = true; 628 th.checkType = '2'; 629 if (th.getAttribute('heap-type') === 'native_hook_statistic') { 630 selection.nativeMemoryStatistic.push(th.rowId!); 631 } else { 632 selection.nativeMemory.push(th.rowId!); 633 } 634 }); 635 info('load nativeMemory traceRow id is : ', it.rowId); 636 } else if (it.rowType == TraceRow.ROW_TYPE_STATIC_INIT) { 637 selection.staticInit = true; 638 this.pushPidToSelection(selection, it.rowParentId!); 639 info('load thread traceRow id is : ', it.rowId); 640 } else if (it.rowType == TraceRow.ROW_TYPE_APP_STARTUP) { 641 selection.startup = true; 642 this.pushPidToSelection(selection, it.rowParentId!); 643 info('load thread traceRow id is : ', it.rowId); 644 } else if (it.rowType == TraceRow.ROW_TYPE_THREAD) { 645 this.pushPidToSelection(selection, it.rowParentId!); 646 selection.threadIds.push(parseInt(it.rowId!)); 647 info('load thread traceRow id is : ', it.rowId); 648 } else if (it.rowType == TraceRow.ROW_TYPE_FUNC) { 649 TabPaneTaskFrames.TaskArray = []; 650 this.pushPidToSelection(selection, it.rowParentId!); 651 if (it.asyncFuncName) { 652 selection.funAsync.push({ 653 name: it.asyncFuncName, 654 pid: it.asyncFuncNamePID || 0, 655 }); 656 } else { 657 selection.funTids.push(parseInt(it.rowId!)); 658 } 659 660 let isIntersect = (filterFunc: FuncStruct, rangeData: RangeSelectStruct) => 661 Math.max(filterFunc.startTs! + filterFunc.dur!, rangeData!.endNS || 0) - Math.min(filterFunc.startTs!, rangeData!.startNS || 0) < 662 filterFunc.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0) && filterFunc.funName!.indexOf('H:Task ') >= 0; 663 let taskData = it.dataList.filter((taskData: FuncStruct) => { 664 taskData!.tid = parseInt(it.rowId!); 665 return isIntersect(taskData, TraceRow.rangeSelectObject!); 666 }); 667 if (taskData.length > 0) { 668 selection.taskFramesData.push(...taskData); 669 } 670 info('load func traceRow id is : ', it.rowId); 671 } else if (it.rowType == TraceRow.ROW_TYPE_MEM || it.rowType == TraceRow.ROW_TYPE_VIRTUAL_MEMORY) { 672 if (it.rowType == TraceRow.ROW_TYPE_MEM) { 673 selection.processTrackIds.push(parseInt(it.rowId!)); 674 } else { 675 selection.virtualTrackIds.push(parseInt(it.rowId!)); 676 } 677 info('load memory traceRow id is : ', it.rowId); 678 } else if (it.rowType == TraceRow.ROW_TYPE_FPS) { 679 selection.hasFps = true; 680 info('load FPS traceRow id is : ', it.rowId); 681 } else if (it.rowType == TraceRow.ROW_TYPE_HEAP) { 682 if (it.getAttribute('heap-type') === 'native_hook_statistic') { 683 selection.nativeMemoryStatistic.push(it.rowId!); 684 } else { 685 selection.nativeMemory.push(it.rowId!); 686 } 687 info('load nativeMemory traceRow id is : ', it.rowId); 688 } else if (it.rowType == TraceRow.ROW_TYPE_MONITOR) { 689 let abilityChildRows: Array<TraceRow<any>> = [ 690 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 691 ]; 692 if (!it.expansion) { 693 abilityChildRows = [...it.childrenList]; 694 } 695 abilityChildRows.forEach((th) => { 696 th.rangeSelect = true; 697 th.checkType = '2'; 698 if (th.rowType == TraceRow.ROW_TYPE_CPU_ABILITY) { 699 selection.cpuAbilityIds.push(th.rowId!); 700 } else if (th.rowType == TraceRow.ROW_TYPE_MEMORY_ABILITY) { 701 selection.memoryAbilityIds.push(th.rowId!); 702 } else if (th.rowType == TraceRow.ROW_TYPE_DISK_ABILITY) { 703 selection.diskAbilityIds.push(th.rowId!); 704 } else if (th.rowType == TraceRow.ROW_TYPE_NETWORK_ABILITY) { 705 selection.networkAbilityIds.push(th.rowId!); 706 } else if (th.rowType == TraceRow.ROW_TYPE_DMA_ABILITY) { 707 selection.dmaAbilityData.push(...intersectData(th)!); 708 } else if (th.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY) { 709 selection.gpuMemoryAbilityData.push(...intersectData(th)!); 710 } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY) { 711 selection.purgeableTotalAbility.push(...intersectData(th)); 712 } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY) { 713 selection.purgeablePinAbility.push(...intersectData(th)); 714 } 715 }); 716 } else if (it.rowType == TraceRow.ROW_TYPE_CPU_ABILITY) { 717 selection.cpuAbilityIds.push(it.rowId!); 718 info('load CPU Ability traceRow id is : ', it.rowId); 719 } else if (it.rowType == TraceRow.ROW_TYPE_MEMORY_ABILITY) { 720 selection.memoryAbilityIds.push(it.rowId!); 721 info('load Memory Ability traceRow id is : ', it.rowId); 722 } else if (it.rowType == TraceRow.ROW_TYPE_DISK_ABILITY) { 723 selection.diskAbilityIds.push(it.rowId!); 724 info('load DiskIo Ability traceRow id is : ', it.rowId); 725 } else if (it.rowType == TraceRow.ROW_TYPE_NETWORK_ABILITY) { 726 selection.networkAbilityIds.push(it.rowId!); 727 info('load Network Ability traceRow id is : ', it.rowId); 728 } else if (it.rowType == TraceRow.ROW_TYPE_DMA_ABILITY) { 729 selection.dmaAbilityData.push(...intersectData(it)!); 730 } else if (it.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY) { 731 selection.gpuMemoryAbilityData.push(...intersectData(it)!); 732 } else if (it.rowType?.startsWith(TraceRow.ROW_TYPE_SDK)) { 733 if (it.rowType == TraceRow.ROW_TYPE_SDK) { 734 let sdkRows: Array<TraceRow<any>> = [ 735 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 736 ]; 737 if (!it.expansion) { 738 sdkRows = [...it.childrenList]; 739 } 740 sdkRows.forEach((th) => { 741 th.rangeSelect = true; 742 th.checkType = '2'; 743 }); 744 } 745 if (it.rowType == TraceRow.ROW_TYPE_SDK_COUNTER) { 746 selection.sdkCounterIds.push(it.rowId!); 747 } 748 if (it.rowType == TraceRow.ROW_TYPE_SDK_SLICE) { 749 selection.sdkSliceIds.push(it.rowId!); 750 } 751 } else if (it.rowType?.startsWith('hiperf')) { 752 if (it.rowType == TraceRow.ROW_TYPE_HIPERF_EVENT || it.rowType == TraceRow.ROW_TYPE_HIPERF_REPORT) { 753 return; 754 } 755 selection.perfSampleIds.push(1); 756 if (it.rowType == TraceRow.ROW_TYPE_HIPERF_PROCESS) { 757 let hiperfProcessRows: Array<TraceRow<any>> = [ 758 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 759 ]; 760 if (!it.expansion) { 761 hiperfProcessRows = [...it.childrenList]; 762 } 763 hiperfProcessRows.forEach((th) => { 764 th.rangeSelect = true; 765 th.checkType = '2'; 766 }); 767 } 768 if (it.rowType == TraceRow.ROW_TYPE_HIPERF || it.rowId == 'HiPerf-cpu-merge') { 769 selection.perfAll = true; 770 } 771 if (it.rowType == TraceRow.ROW_TYPE_HIPERF_CPU) { 772 selection.perfCpus.push(it.index); 773 } 774 if (it.rowType == TraceRow.ROW_TYPE_HIPERF_PROCESS) { 775 selection.perfProcess.push(parseInt(it.rowId!.split('-')[0])); 776 } 777 if (it.rowType == TraceRow.ROW_TYPE_HIPERF_THREAD) { 778 selection.perfThread.push(parseInt(it.rowId!.split('-')[0])); 779 } 780 } else if (it.rowType == TraceRow.ROW_TYPE_FILE_SYSTEM) { 781 if (it.rowId == 'FileSystemLogicalWrite') { 782 if (selection.fileSystemType.length == 0) { 783 selection.fileSystemType = [0, 1, 3]; 784 } else { 785 if (selection.fileSystemType.indexOf(3) == -1) { 786 selection.fileSystemType.push(3); 787 } 788 } 789 } else if (it.rowId == 'FileSystemLogicalRead') { 790 if (selection.fileSystemType.length == 0) { 791 selection.fileSystemType = [0, 1, 2]; 792 } else { 793 if (selection.fileSystemType.indexOf(2) == -1) { 794 selection.fileSystemType.push(2); 795 } 796 } 797 } else if (it.rowId == 'FileSystemVirtualMemory') { 798 selection.fileSysVirtualMemory = true; 799 } else if (it.rowId == 'FileSystemDiskIOLatency') { 800 selection.diskIOLatency = true; 801 } else { 802 if (!selection.diskIOLatency) { 803 let arr = it.rowId!.split('-').reverse(); 804 let ipid = parseInt(arr[0]); 805 if (selection.diskIOipids.indexOf(ipid) == -1) { 806 selection.diskIOipids.push(ipid); 807 } 808 if (arr[1] == 'read') { 809 selection.diskIOReadIds.indexOf(ipid) == -1 ? selection.diskIOReadIds.push(ipid) : ''; 810 } else if (arr[1] == 'write') { 811 selection.diskIOWriteIds.indexOf(ipid) == -1 ? selection.diskIOWriteIds.push(ipid) : ''; 812 } 813 } 814 } 815 } else if (it.rowType == TraceRow.ROW_TYPE_POWER_ENERGY) { 816 selection.powerEnergy.push(it.rowId!); 817 } else if (it.rowType == TraceRow.ROW_TYPE_SYSTEM_ENERGY) { 818 selection.systemEnergy.push(it.rowId!); 819 } else if (it.rowType == TraceRow.ROW_TYPE_ANOMALY_ENERGY) { 820 selection.anomalyEnergy.push(it.rowId!); 821 } else if (it.rowType == TraceRow.ROW_TYPE_SYSTEM_ENERGY) { 822 info('load anomaly Energy traceRow id is : ', it.rowId); 823 } else if (it.rowType == TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) { 824 selection.smapsType.push(...intersectData(it)!); 825 let sMapsChildRows: Array<TraceRow<any>> = [ 826 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 827 ]; 828 if (!it.expansion) { 829 sMapsChildRows = [...it.childrenList]; 830 } 831 sMapsChildRows.forEach((item) => { 832 item.rangeSelect = true; 833 if (item.rowType == TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) { 834 selection.smapsType.push(...intersectData(item)!); 835 } 836 }); 837 } else if (it.rowType == TraceRow.ROW_TYPE_VMTRACKER_SHM) { 838 selection.vmtrackershm.push(...intersectData(it)!); 839 } else if (it.rowType == TraceRow.ROW_TYPE_CLOCK) { 840 selection.clockMapData.set( 841 it.rowId || '', 842 it.dataList.filter((clockData) => { 843 return Utils.getTimeIsCross( 844 clockData.startNS, 845 clockData.startNS + clockData.dur, 846 TraceRow.rangeSelectObject?.startNS || 0, 847 TraceRow.rangeSelectObject?.endNS || 0 848 ); 849 }) 850 ); 851 } else if (it.rowType == TraceRow.ROW_TYPE_IRQ) { 852 it.dataList.forEach((irqData) => { 853 if ( 854 Utils.getTimeIsCross( 855 irqData.startNS, 856 irqData.startNS + irqData.dur, 857 TraceRow.rangeSelectObject?.startNS || 0, 858 TraceRow.rangeSelectObject?.endNS || 0 859 ) 860 ) { 861 if (selection.irqMapData.has(irqData.name)) { 862 selection.irqMapData.get(irqData.name)?.push(irqData); 863 } else { 864 selection.irqMapData.set(irqData.name, [irqData]); 865 } 866 } 867 }); 868 } else if (it.rowType === TraceRow.ROW_TYPE_VM_TRACKER) { 869 let vMTrackerChildRows: Array<TraceRow<any>> = [ 870 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 871 ]; 872 if (!it.expansion) { 873 vMTrackerChildRows = [...it.childrenList]; 874 } 875 vMTrackerChildRows.forEach((th) => { 876 th.rangeSelect = true; 877 if (th.rowType === TraceRow.ROW_TYPE_DMA_VMTRACKER) { 878 selection.dmaVmTrackerData.push(...intersectData(th)!); 879 } else if (th.rowType === TraceRow.ROW_TYPE_SYS_MEMORY_GPU) { 880 let vMTrackerGpuChildRows: Array<TraceRow<any>> = [ 881 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${th.rowId}']`), 882 ]; 883 if (!th.expansion) { 884 vMTrackerGpuChildRows = [...th.childrenList]; 885 } 886 vMTrackerGpuChildRows.forEach((item) => { 887 item.rangeSelect = true; 888 if (item.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER) { 889 selection.gpuMemoryTrackerData.push(...intersectData(item)!); 890 } else if (item.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_GL) { 891 selection.gpu.gl = 892 item.dataList.filter( 893 (it) => 894 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 895 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 896 ).length > 0; 897 } else if (item.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL) { 898 selection.gpu.gpuTotal = 899 item.dataList.filter( 900 (it) => 901 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 902 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 903 ).length > 0; 904 } else if (item.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW) { 905 selection.gpu.gpuWindow = 906 item.dataList.filter( 907 (it) => 908 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 909 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 910 ).length > 0; 911 } 912 }); 913 } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM) { 914 selection.purgeableTotalVM.push(...intersectData(th)); 915 } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_VM) { 916 selection.purgeablePinVM.push(...intersectData(th)); 917 } else if (th.rowType === TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) { 918 let sMapsChildRows: Array<TraceRow<any>> = [ 919 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${th.rowId}']`), 920 ]; 921 if (!th.expansion) { 922 sMapsChildRows = [...th.childrenList]; 923 } 924 sMapsChildRows.forEach((item) => { 925 item.rangeSelect = true; 926 if (item.rowType == TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) { 927 selection.smapsType.push(...intersectData(item)!); 928 } 929 }); 930 } else if (th.rowType == TraceRow.ROW_TYPE_VMTRACKER_SHM) { 931 selection.vmtrackershm.push(...intersectData(th)!); 932 } 933 }); 934 } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU) { 935 let vMTrackerGpuChildRows: Array<TraceRow<any>> = [ 936 ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`), 937 ]; 938 if (!it.expansion) { 939 vMTrackerGpuChildRows = [...it.childrenList]; 940 } 941 vMTrackerGpuChildRows.forEach((th) => { 942 th.rangeSelect = true; 943 if (th.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER) { 944 selection.gpuMemoryTrackerData.push(...intersectData(th)!); 945 } else if (th.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_GL) { 946 selection.gpu.gl = 947 th.dataList.filter( 948 (it) => 949 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 950 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 951 ).length > 0; 952 } else if (th.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL) { 953 selection.gpu.gpuTotal = 954 th.dataList.filter( 955 (it) => 956 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 957 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 958 ).length > 0; 959 } else if (th.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW) { 960 selection.gpu.gpuWindow = 961 th.dataList.filter( 962 (it) => 963 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 964 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 965 ).length > 0; 966 } 967 }); 968 } else if (it.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER) { 969 selection.gpuMemoryTrackerData.push(...intersectData(it)!); 970 } else if (it.rowType == TraceRow.ROW_TYPE_DMA_VMTRACKER) { 971 selection.dmaVmTrackerData.push(...intersectData(it)!); 972 } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_GL) { 973 selection.gpu.gl = 974 it.dataList.filter( 975 (it) => 976 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 977 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 978 ).length > 0; 979 } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL) { 980 selection.gpu.gpuTotal = 981 it.dataList.filter( 982 (it) => 983 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 984 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 985 ).length > 0; 986 } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW) { 987 selection.gpu.gpuWindow = 988 it.dataList.filter( 989 (it) => 990 (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) || 991 (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs) 992 ).length > 0; 993 } else if (it.rowType == TraceRow.ROW_TYPE_JANK) { 994 let isIntersect = (filterJank: JanksStruct, rangeData: RangeSelectStruct) => 995 Math.max(filterJank.ts! + filterJank.dur!, rangeData!.endNS || 0) - Math.min(filterJank.ts!, rangeData!.startNS || 0) < 996 filterJank.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0); 997 if (it.name == 'Actual Timeline') { 998 selection.jankFramesData = []; 999 let jankDatas = it.dataList.filter((jankData: any) => { 1000 return isIntersect(jankData, TraceRow.rangeSelectObject!); 1001 }); 1002 selection.jankFramesData.push(jankDatas); 1003 } else if (it.folder) { 1004 selection.jankFramesData = []; 1005 it.childrenList.forEach((child) => { 1006 if (child.rowType == TraceRow.ROW_TYPE_JANK && child.name == 'Actual Timeline') { 1007 let jankDatas = child.dataList.filter((jankData: any) => { 1008 return isIntersect(jankData, TraceRow.rangeSelectObject!); 1009 }); 1010 selection.jankFramesData.push(jankDatas); 1011 } 1012 }); 1013 } 1014 } else if (it.rowType == TraceRow.ROW_TYPE_HEAP_TIMELINE) { 1015 let endNS = TraceRow.rangeSelectObject?.endNS ? TraceRow.rangeSelectObject?.endNS : TraceRow.range?.endNS; 1016 let startNS = TraceRow.rangeSelectObject?.startNS 1017 ? TraceRow.rangeSelectObject?.startNS 1018 : TraceRow.range?.startNS; 1019 let minNodeId, maxNodeId; 1020 if (!it.dataList || it.dataList.length === 0) { 1021 return; 1022 } 1023 for (let sample of it.dataList) { 1024 if (sample.timestamp * 1000 <= startNS!) { 1025 minNodeId = sample.lastAssignedId; 1026 } 1027 if (sample.timestamp * 1000 >= endNS!) { 1028 if (maxNodeId === undefined) { 1029 maxNodeId = sample.lastAssignedId; 1030 } 1031 } 1032 } 1033 1034 // If the start time range of the selected box is greater than the end time of the sampled data 1035 if (startNS! >= it.dataList[it.dataList.length - 1].timestamp * 1000) { 1036 minNodeId = it.dataList[it.dataList.length - 1].lastAssignedId; 1037 } 1038 // If you select the box from the beginning 1039 if (startNS! <= TraceRow.range?.startNS!) { 1040 minNodeId = HeapDataInterface.getInstance().getMinNodeId(this.snapshotFiles!.id); 1041 } 1042 //If you select the box from the ending 1043 if (endNS! >= TraceRow.range?.endNS! || endNS! >= it.dataList[it.dataList.length - 1].timestampUs * 1000) { 1044 maxNodeId = HeapDataInterface.getInstance().getMaxNodeId(this.snapshotFiles!.id); 1045 } 1046 let summary = (this.traceSheetEL?.shadowRoot?.querySelector('#tabs') as LitTabs) 1047 ?.querySelector('#box-heap-summary') 1048 ?.querySelector('tabpane-summary') as TabPaneSummary; 1049 summary.initSummaryData(this.snapshotFiles!, minNodeId, maxNodeId); 1050 selection.jsMemory.push(1); 1051 } else if (it.rowType == TraceRow.ROW_TYPE_JS_CPU_PROFILER) { 1052 let isIntersect = (a: JsCpuProfilerStruct, b: RangeSelectStruct) => 1053 Math.max(a.startTime! + a.totalTime!, b!.endNS || 0) - Math.min(a.startTime!, b!.startNS || 0) < 1054 a.totalTime! + (b!.endNS || 0) - (b!.startNS || 0); 1055 let frameSelectData = it.dataList.filter((frameSelectData: any) => { 1056 return isIntersect(frameSelectData, TraceRow.rangeSelectObject!); 1057 }); 1058 let copyFrameSelectData = JSON.parse(JSON.stringify(frameSelectData)); 1059 let frameSelectDataIdArr: Array<number> = []; 1060 for (let data of copyFrameSelectData) { 1061 frameSelectDataIdArr.push(data.id); 1062 } 1063 let jsCpuProfilerData = copyFrameSelectData.filter((item: any) => { 1064 if (item.depth == 0) { 1065 setSelectState(item, frameSelectDataIdArr); 1066 return item; 1067 } 1068 }); 1069 selection.jsCpuProfilerData = jsCpuProfilerData; 1070 } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_ANIMATION) { 1071 let isIntersect = (animationStruct: FrameAnimationStruct, selectStruct: RangeSelectStruct) => 1072 Math.max(animationStruct.ts! + animationStruct.dur!, selectStruct!.endNS || 0) - 1073 Math.min(animationStruct.ts!, selectStruct!.startNS || 0) < 1074 animationStruct.dur! + (selectStruct!.endNS || 0) - (selectStruct!.startNS || 0); 1075 let frameAnimationList = it.dataList.filter((frameAnimationBean: FrameAnimationStruct) => { 1076 return isIntersect(frameAnimationBean, TraceRow.rangeSelectObject!); 1077 }); 1078 selection.frameAnimation.push(...frameAnimationList); 1079 } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_DYNAMIC) { 1080 let appName = it.getAttribute('model-name'); 1081 let isSelect = (dynamicStruct: FrameDynamicStruct, b: RangeSelectStruct) => 1082 dynamicStruct.ts >= b.startNS! && dynamicStruct.ts <= b.endNS!; 1083 let frameDynamicList = it.dataList.filter( 1084 (frameAnimationBean: FrameDynamicStruct) => 1085 isSelect(frameAnimationBean, TraceRow.rangeSelectObject!) && 1086 frameAnimationBean.groupId !== -1 && 1087 frameAnimationBean.appName === appName 1088 ); 1089 selection.frameDynamic.push(...frameDynamicList); 1090 } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_SPACING) { 1091 let appName = it.getAttribute('model-name'); 1092 let isSelect = (a: FrameSpacingStruct, b: RangeSelectStruct) => 1093 a.currentTs >= b.startNS! && a.currentTs <= b.endNS!; 1094 let frameDatas = it.dataList.filter((frameData: FrameSpacingStruct) => { 1095 return ( 1096 isSelect(frameData, TraceRow.rangeSelectObject!) && 1097 frameData.groupId !== -1 && 1098 frameData.frameSpacingResult !== -1 && 1099 frameData.nameId === appName 1100 ); 1101 }); 1102 selection.frameSpacing.push(...frameDatas); 1103 } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY) { 1104 selection.purgeableTotalAbility.push(...intersectData(it)); 1105 } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY) { 1106 selection.purgeablePinAbility.push(...intersectData(it)); 1107 } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM) { 1108 selection.purgeableTotalVM.push(...intersectData(it)); 1109 } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_PIN_VM) { 1110 selection.purgeablePinVM.push(...intersectData(it)); 1111 } 1112 if (this.rangeTraceRow!.length !== rows.length) { 1113 let event = this.createPointEvent(it); 1114 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 1115 action: 'trace_row', 1116 event: event, 1117 }); 1118 } 1119 }); 1120 this.rangeTraceRow = rows; 1121 this.isSelectClick = false; 1122 if (selection.diskIOipids.length > 0 && !selection.diskIOLatency) { 1123 selection.promiseList.push( 1124 queryEbpfSamplesCount( 1125 TraceRow.rangeSelectObject?.startNS || 0, 1126 TraceRow.rangeSelectObject?.endNS || 0, 1127 selection.diskIOipids 1128 ).then((res) => { 1129 if (res.length > 0) { 1130 selection.fsCount = res[0].fsCount; 1131 selection.vmCount = res[0].vmCount; 1132 } 1133 return new Promise((resolve) => resolve(1)); 1134 }) 1135 ); 1136 } 1137 this.selectStructNull(); 1138 this.timerShaftEL?.removeTriangle('inverted'); 1139 if (selection.promiseList.length > 0) { 1140 Promise.all(selection.promiseList).then(() => { 1141 selection.promiseList = []; 1142 this.traceSheetEL?.rangeSelect(selection); 1143 }); 1144 } else { 1145 this.traceSheetEL?.rangeSelect(selection); 1146 } 1147 this.timerShaftEL!.selectionList.push(selection); // 保持选中对象,为后面的再次选中该框选区域做准备。 1148 this.selectionParam = selection; 1149 }; 1150 // @ts-ignore 1151 new ResizeObserver((entries) => { 1152 TraceRow.FRAME_WIDTH = this.clientWidth - 249 - this.getScrollWidth(); 1153 requestAnimationFrame(() => { 1154 this.timerShaftEL?.updateWidth(this.clientWidth - 1 - this.getScrollWidth()); 1155 this.shadowRoot!.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => { 1156 it.updateWidth(this.clientWidth); 1157 }); 1158 }); 1159 }).observe(this); 1160 1161 new ResizeObserver((entries) => { 1162 this.canvasPanelConfig(); 1163 if (this.traceSheetEL!.getAttribute('mode') == 'hidden') { 1164 this.timerShaftEL?.removeTriangle('triangle'); 1165 } 1166 this.refreshFavoriteCanvas(); 1167 this.refreshCanvas(true); 1168 }).observe(this.rowsPaneEL!); 1169 new MutationObserver((mutations, observer) => { 1170 for (const mutation of mutations) { 1171 if (mutation.type === 'attributes') { 1172 if (this.style.visibility === 'visible') { 1173 if (TraceRow.rangeSelectObject && SpSystemTrace.sliceRangeMark) { 1174 this.timerShaftEL?.setSlicesMark( 1175 TraceRow.rangeSelectObject.startNS || 0, 1176 TraceRow.rangeSelectObject.endNS || 0, 1177 false 1178 ); 1179 SpSystemTrace.sliceRangeMark = undefined; 1180 window.publish(window.SmartEvent.UI.RefreshCanvas, {}); 1181 } 1182 } 1183 } 1184 } 1185 }).observe(this, { 1186 attributes: true, 1187 childList: false, 1188 subtree: false, 1189 }); 1190 1191 this.intersectionObserver = new IntersectionObserver((entries) => { 1192 entries.forEach((it) => { 1193 let tr = it.target as TraceRow<any>; 1194 if (!it.isIntersecting) { 1195 tr.sleeping = true; 1196 this.visibleRows = this.visibleRows.filter((it) => !it.sleeping); 1197 } else { 1198 if ( 1199 !this.visibleRows.find( 1200 (vr) => vr.rowId === tr.rowId && vr.rowType === tr.rowType && vr.rowParentId === tr.rowParentId 1201 ) 1202 ) { 1203 this.visibleRows.push(tr); 1204 } 1205 tr.sleeping = false; 1206 } 1207 if (this.handler) clearTimeout(this.handler); 1208 this.handler = setTimeout(() => this.refreshCanvas(false), 100); 1209 }); 1210 }); 1211 window.addEventListener('keydown', (ev) => { 1212 if (ev.key.toLocaleLowerCase() === 'escape') { 1213 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => { 1214 it.checkType = '-1'; 1215 }); 1216 TraceRow.rangeSelectObject = undefined; 1217 this.rangeSelect.rangeTraceRow = []; 1218 this.selectStructNull(); 1219 this.timerShaftEL?.setSlicesMark(); 1220 this.traceSheetEL?.setAttribute('mode', 'hidden'); 1221 this.removeLinkLinesByBusinessType('janks', 'task'); 1222 } 1223 }); 1224 this.chartManager = new SpChartManager(this); 1225 this.canvasPanel = this.shadowRoot!.querySelector<HTMLCanvasElement>('#canvas-panel')!; 1226 this.canvasFavoritePanel = this.shadowRoot!.querySelector<HTMLCanvasElement>('#canvas-panel-favorite')!; 1227 this.canvasPanelCtx = this.canvasPanel.getContext('2d'); 1228 1229 this.canvasFavoritePanelCtx = this.canvasFavoritePanel.getContext('2d'); 1230 this.canvasPanelConfig(); 1231 window.subscribe(window.SmartEvent.UI.SliceMark, (data) => { 1232 this.sliceMarkEventHandler(data); 1233 }); 1234 window.subscribe(window.SmartEvent.UI.TraceRowComplete, (tr) => {}); 1235 window.subscribe(window.SmartEvent.UI.RefreshCanvas, () => { 1236 this.refreshCanvas(false); 1237 }); 1238 window.subscribe(window.SmartEvent.UI.KeyboardEnable, (tr) => { 1239 this.keyboardEnable = tr.enable; 1240 if (!this.keyboardEnable) { 1241 this.stopWASD(); 1242 } 1243 }); 1244 window.subscribe(window.SmartEvent.UI.MouseEventEnable, (tr) => { 1245 this.mouseEventEnable = tr.mouseEnable; 1246 if (this.mouseEventEnable) { 1247 this.removeAttribute('disable'); 1248 } else { 1249 this.setAttribute('disable', ''); 1250 } 1251 }); 1252 } 1253 1254 pushPidToSelection(selection: SelectionParam, id: string) { 1255 let pid = parseInt(id); 1256 if (!selection.processIds.includes(pid)) { 1257 selection.processIds.push(pid); 1258 } 1259 } 1260 1261 private createPointEvent(it: TraceRow<any>) { 1262 let event = this.eventMap[it.rowType + '']; 1263 if (event) { 1264 return event; 1265 } else { 1266 if (it.rowType === TraceRow.ROW_TYPE_HEAP) { 1267 event = it.name; 1268 } else if (it.rowType === TraceRow.ROW_TYPE_HIPERF_CPU) { 1269 event = 'HiPerf Cpu'; 1270 if (it.rowId === 'HiPerf-cpu-merge') { 1271 event = 'HiPerf'; 1272 } 1273 } else if (it.rowType === TraceRow.ROW_TYPE_FILE_SYSTEM) { 1274 if (it.rowId === 'FileSystemLogicalWrite') { 1275 event = 'FileSystem Logical Write'; 1276 } else if (it.rowId === 'FileSystemLogicalRead') { 1277 event = 'FileSystem Logical Read'; 1278 } else if (it.rowId === 'FileSystemVirtualMemory') { 1279 event = 'Page Fault Trace'; 1280 } else if (it.rowId!.startsWith('FileSystemDiskIOLatency')) { 1281 event = 'Disk I/O Latency'; 1282 if (it.rowId!.startsWith('FileSystemDiskIOLatency-')) { 1283 event = 'Bio Process'; 1284 } 1285 } 1286 } else if (it.rowType === TraceRow.ROW_TYPE_STATE_ENERGY) { 1287 event = it.name; 1288 } else if (it.rowType === TraceRow.ROW_TYPE_VM_TRACKER) { 1289 if (it.rowParentId === '') { 1290 event = 'VM Tracker'; 1291 } else { 1292 event = it.name; 1293 } 1294 } else if (it.rowType === TraceRow.ROW_TYPE_JANK) { 1295 if (it.rowId === 'frameTime' || it.rowParentId === 'frameTime') { 1296 event = 'FrameTimeLine'; 1297 } else if (it.hasAttribute('frame_type')) { 1298 event = it.getAttribute('frame_type') + ''; 1299 } 1300 } else if (it.rowType === TraceRow.ROW_TYPE_DELIVER_INPUT_EVENT) { 1301 event = 'DeliverInputEvent'; 1302 if (it.rowParentId === TraceRow.ROW_TYPE_DELIVER_INPUT_EVENT) { 1303 event = 'DeliverInputEvent Func'; 1304 } 1305 } else { 1306 event = it.name; 1307 } 1308 return event; 1309 } 1310 } 1311 1312 refreshFavoriteCanvas() { 1313 let collectList = this.favoriteRowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[collect-type]`) || []; 1314 let height = 0; 1315 collectList.forEach((row, index) => { 1316 height += row.offsetHeight; 1317 if (index == collectList.length - 1) { 1318 row.style.boxShadow = `0 10px 10px #00000044`; 1319 } else { 1320 row.style.boxShadow = `0 10px 10px #00000000`; 1321 } 1322 }); 1323 if (height > this.rowsPaneEL!.offsetHeight) { 1324 this.favoriteRowsEL!.style.height = this.rowsPaneEL!.offsetHeight + 'px'; 1325 } else { 1326 this.favoriteRowsEL!.style.height = height + 'px'; 1327 } 1328 this.favoriteRowsEL!.style.width = this.canvasPanel?.offsetWidth + 'px'; 1329 this.spacerEL!.style.height = height + 'px'; 1330 this.canvasFavoritePanel!.style.height = this.favoriteRowsEL!.style.height; 1331 this.canvasFavoritePanel!.style.width = this.canvasPanel?.offsetWidth + 'px'; 1332 this.canvasFavoritePanel!.width = this.canvasFavoritePanel!.offsetWidth * dpr(); 1333 this.canvasFavoritePanel!.height = this.canvasFavoritePanel!.offsetHeight * dpr(); 1334 this.canvasFavoritePanel!.getContext('2d')!.scale(dpr(), dpr()); 1335 } 1336 1337 expansionAllParentRow(currentRow: TraceRow<any>) { 1338 let parentRow = this.rowsEL!.querySelector<TraceRow<any>>( 1339 `trace-row[row-id='${currentRow.rowParentId}'][folder][scene]` 1340 ); 1341 if (parentRow) { 1342 parentRow.expansion = true; 1343 if (this.rowsEL!.querySelector<TraceRow<any>>(`trace-row[row-id='${parentRow.rowParentId}'][folder]`)) { 1344 this.expansionAllParentRow(parentRow); 1345 } 1346 } 1347 } 1348 1349 canvasPanelConfig() { 1350 this.canvasPanel!.style.left = `${this.timerShaftEL!.canvas!.offsetLeft!}px`; 1351 this.canvasPanel!.width = this.canvasPanel!.offsetWidth * dpr(); 1352 this.canvasPanel!.height = this.canvasPanel!.offsetHeight * dpr(); 1353 this.canvasPanelCtx!.scale(dpr(), dpr()); 1354 1355 this.canvasFavoritePanel!.style.left = `${this.timerShaftEL!.canvas!.offsetLeft!}px`; 1356 this.canvasFavoritePanel!.width = this.canvasFavoritePanel!.offsetWidth * dpr(); 1357 this.canvasFavoritePanel!.height = this.canvasFavoritePanel!.offsetHeight * dpr(); 1358 this.canvasFavoritePanelCtx!.scale(dpr(), dpr()); 1359 } 1360 1361 getScrollWidth() { 1362 let totalScrollDiv, 1363 scrollDiv, 1364 overflowDiv = document.createElement('div'); 1365 overflowDiv.style.cssText = 'position:absolute; top:-2000px;width:200px; height:200px; overflow:hidden;'; 1366 totalScrollDiv = document.body.appendChild(overflowDiv).clientWidth; 1367 overflowDiv.style.overflowY = 'scroll'; 1368 scrollDiv = overflowDiv.clientWidth; 1369 document.body.removeChild(overflowDiv); 1370 return totalScrollDiv - scrollDiv; 1371 } 1372 1373 timerShaftELFlagClickHandler = (flag: Flag | undefined | null) => { 1374 if (flag) { 1375 setTimeout(() => { 1376 this.traceSheetEL?.displayFlagData(flag); 1377 }, 100); 1378 } 1379 }; 1380 1381 timerShaftELFlagChange = (hoverFlag: Flag | undefined | null, selectFlag: Flag | undefined | null) => { 1382 this.hoverFlag = hoverFlag; 1383 this.selectFlag = selectFlag; 1384 this.refreshCanvas(true, 'flagChange'); 1385 }; 1386 1387 timerShaftELRangeClick = (sliceTime: SlicesTime | undefined | null) => { 1388 if (sliceTime) { 1389 setTimeout(() => { 1390 this.traceSheetEL?.displayCurrent(sliceTime); // 给当前pane准备数据 1391 let selection = this.timerShaftEL!.selectionMap.get(sliceTime.id); 1392 if (selection) { 1393 selection.isCurrentPane = true; // 设置当前面板为可以显示的状态 1394 this.traceSheetEL?.rangeSelect(selection); // 显示选中区域对应的面板 1395 } 1396 }, 0); 1397 } 1398 }; 1399 1400 timerShaftELRangeChange = (e: any) => { 1401 TraceRow.range = e; 1402 if (TraceRow.rangeSelectObject) { 1403 TraceRow.rangeSelectObject!.startX = Math.floor( 1404 ns2x( 1405 TraceRow.rangeSelectObject!.startNS!, 1406 TraceRow.range?.startNS!, 1407 TraceRow.range?.endNS!, 1408 TraceRow.range?.totalNS!, 1409 this.timerShaftEL!.sportRuler!.frame 1410 ) 1411 ); 1412 TraceRow.rangeSelectObject!.endX = Math.floor( 1413 ns2x( 1414 TraceRow.rangeSelectObject!.endNS!, 1415 TraceRow.range?.startNS!, 1416 TraceRow.range?.endNS!, 1417 TraceRow.range?.totalNS!, 1418 this.timerShaftEL!.sportRuler!.frame 1419 ) 1420 ); 1421 } 1422 //在rowsEL显示范围内的 trace-row组件将收到时间区间变化通知 1423 this.linkNodes.forEach((it) => { 1424 it[0].x = ns2xByTimeShaft(it[0].ns, this.timerShaftEL!); 1425 it[1].x = ns2xByTimeShaft(it[1].ns, this.timerShaftEL!); 1426 }); 1427 this.refreshCanvas(false, 'rangeChange'); 1428 }; 1429 tim: number = -1; 1430 top: number = 0; 1431 handler: any = undefined; 1432 rowsElOnScroll = (e: any) => { 1433 this.linkNodes.forEach((itln) => { 1434 if (itln[0].rowEL.collect) { 1435 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 1436 } else { 1437 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 1438 } 1439 if (itln[1].rowEL.collect) { 1440 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 1441 } else { 1442 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 1443 } 1444 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 1445 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 1446 }); 1447 if (this.scrollTimer) { 1448 clearTimeout(this.scrollTimer); 1449 } 1450 this.scrollTimer = setTimeout(() => { 1451 TraceRow.range!.refresh = true; 1452 requestAnimationFrame(() => this.refreshCanvas(false)); 1453 }, 200); 1454 requestAnimationFrame(() => this.refreshCanvas(false)); 1455 }; 1456 1457 private scrollTimer: any; 1458 1459 favoriteRowsElOnScroll = (e: any) => { 1460 this.rowsElOnScroll(e); 1461 }; 1462 1463 offset = 147; 1464 1465 getRowsContentHeight(): number { 1466 return [...this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row:not([sleeping])`)] 1467 .map((it) => it.clientHeight) 1468 .reduce((acr, cur) => acr + cur, 0); 1469 } 1470 1471 // refresh main canvas and favorite canvas 1472 refreshCanvas(cache: boolean, from?: string) { 1473 if (this.visibleRows.length == 0) { 1474 return; 1475 } 1476 //clear main canvas 1477 this.canvasPanelCtx?.clearRect(0, 0, this.canvasPanel!.offsetWidth, this.canvasPanel!.offsetHeight); 1478 //clear favorite canvas 1479 this.canvasFavoritePanelCtx?.clearRect( 1480 0, 1481 0, 1482 this.canvasFavoritePanel!.offsetWidth, 1483 this.canvasFavoritePanel!.offsetHeight 1484 ); 1485 //draw lines for main canvas 1486 let rowsContentHeight = this.getRowsContentHeight(); 1487 let canvasHeight = 1488 rowsContentHeight > this.canvasPanel!.clientHeight ? this.canvasPanel!.clientHeight : rowsContentHeight; 1489 canvasHeight += this.canvasFavoritePanel!.clientHeight; 1490 drawLines(this.canvasPanelCtx!, TraceRow.range?.xs || [], canvasHeight, this.timerShaftEL!.lineColor()); 1491 //draw lines for favorite canvas 1492 drawLines( 1493 this.canvasFavoritePanelCtx!, 1494 TraceRow.range?.xs || [], 1495 this.canvasFavoritePanel!.clientHeight, 1496 this.timerShaftEL!.lineColor() 1497 ); 1498 //canvas translate 1499 this.canvasPanel!.style.transform = `translateY(${this.rowsPaneEL!.scrollTop}px)`; 1500 this.canvasFavoritePanel!.style.transform = `translateY(${this.favoriteRowsEL!.scrollTop}px)`; 1501 //draw trace row 1502 this.visibleRows.forEach((v, i) => { 1503 if (v.collect) { 1504 v.translateY = v.getBoundingClientRect().top - 195; 1505 } else { 1506 v.translateY = v.offsetTop - this.rowsPaneEL!.scrollTop; 1507 } 1508 v.draw(cache); 1509 }); 1510 //draw flag line segment for canvas 1511 drawFlagLineSegment( 1512 this.canvasPanelCtx, 1513 this.hoverFlag, 1514 this.selectFlag, 1515 { 1516 x: 0, 1517 y: 0, 1518 width: this.timerShaftEL?.canvas?.clientWidth, 1519 height: this.canvasPanel?.clientHeight, 1520 }, 1521 this.timerShaftEL! 1522 ); 1523 //draw flag line segment for favorite canvas 1524 drawFlagLineSegment( 1525 this.canvasFavoritePanelCtx, 1526 this.hoverFlag, 1527 this.selectFlag, 1528 { 1529 x: 0, 1530 y: 0, 1531 width: this.timerShaftEL?.canvas?.clientWidth, 1532 height: this.canvasFavoritePanel?.clientHeight, 1533 }, 1534 this.timerShaftEL! 1535 ); 1536 //draw wakeup for main canvas 1537 drawWakeUp( 1538 this.canvasPanelCtx, 1539 CpuStruct.wakeupBean, 1540 TraceRow.range!.startNS, 1541 TraceRow.range!.endNS, 1542 TraceRow.range!.totalNS, 1543 { 1544 x: 0, 1545 y: 0, 1546 width: TraceRow.FRAME_WIDTH, 1547 height: this.canvasPanel!.clientHeight!, 1548 } as Rect 1549 ); 1550 //draw wakeup for favorite canvas 1551 drawWakeUp( 1552 this.canvasFavoritePanelCtx, 1553 CpuStruct.wakeupBean, 1554 TraceRow.range!.startNS, 1555 TraceRow.range!.endNS, 1556 TraceRow.range!.totalNS, 1557 { 1558 x: 0, 1559 y: 0, 1560 width: TraceRow.FRAME_WIDTH, 1561 height: this.canvasFavoritePanel!.clientHeight!, 1562 } as Rect 1563 ); 1564 // draw wakeuplist for main canvas 1565 for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) { 1566 if (i + 1 == SpSystemTrace.wakeupList.length) { 1567 return; 1568 } 1569 drawWakeUpList( 1570 this.canvasPanelCtx, 1571 SpSystemTrace.wakeupList[i + 1], 1572 TraceRow.range!.startNS, 1573 TraceRow.range!.endNS, 1574 TraceRow.range!.totalNS, 1575 { 1576 x: 0, 1577 y: 0, 1578 width: this.timerShaftEL!.canvas!.clientWidth, 1579 height: this.canvasPanel!.clientHeight!, 1580 } as Rect 1581 ); 1582 drawWakeUpList( 1583 this.canvasFavoritePanelCtx, 1584 SpSystemTrace.wakeupList[i + 1], 1585 TraceRow.range!.startNS, 1586 TraceRow.range!.endNS, 1587 TraceRow.range!.totalNS, 1588 { 1589 x: 0, 1590 y: 0, 1591 width: this.timerShaftEL!.canvas!.clientWidth, 1592 height: this.canvasFavoritePanel!.clientHeight!, 1593 } as Rect 1594 ); 1595 } 1596 // Draw the connection curve 1597 if (this.linkNodes) { 1598 drawLinkLines(this.canvasPanelCtx!, this.linkNodes, this.timerShaftEL!, false); 1599 drawLinkLines(this.canvasFavoritePanelCtx!, this.linkNodes, this.timerShaftEL!, true); 1600 } 1601 } 1602 1603 documentOnMouseDown = (ev: MouseEvent) => { 1604 if (!this.loadTraceCompleted || !this.mouseEventEnable) return; 1605 if (this.isWASDKeyPress()) { 1606 ev.preventDefault(); 1607 ev.stopPropagation(); 1608 return; 1609 } 1610 TraceRow.isUserInteraction = true; 1611 if (this.isMouseInSheet(ev)) return; 1612 this.observerScrollHeightEnable = false; 1613 if (ev.offsetX > this.timerShaftEL!.canvas!.offsetLeft) { 1614 let x = ev.offsetX - this.timerShaftEL!.canvas!.offsetLeft; 1615 let y = ev.offsetY; 1616 this.timerShaftEL?.documentOnMouseDown(ev); 1617 if ( 1618 this.timerShaftEL!.sportRuler!.frame.contains(x, y) && 1619 x > (TraceRow.rangeSelectObject?.startX || 0) && 1620 x < (TraceRow.rangeSelectObject?.endX || 0) 1621 ) { 1622 let findSlicestime = this.timerShaftEL!.sportRuler?.findSlicesTime(x, y); // 查找帽子 1623 if (!findSlicestime) { 1624 // 如果没有找到帽子,则绘制一个三角形的旗子 1625 let time = Math.round( 1626 (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / this.timerShaftEL!.canvas!.offsetWidth + 1627 TraceRow.range?.startNS! 1628 ); 1629 this.timerShaftEL!.sportRuler!.drawTriangle(time, 'triangle'); 1630 } 1631 } else { 1632 this.rangeSelect.mouseDown(ev); 1633 this.rangeSelect.drag = true; 1634 } 1635 } else { 1636 this.rangeSelect.drag = false; 1637 } 1638 }; 1639 1640 onContextMenuHandler = (e: Event) => { 1641 setTimeout(() => { 1642 for (let key of this.keyPressMap.keys()) { 1643 if (this.keyPressMap.get(key)) { 1644 this.timerShaftEL?.stopWASD({ key: key }); 1645 this.keyPressMap.set(key, false); 1646 } 1647 } 1648 }, 100); 1649 }; 1650 1651 documentOnMouseUp = (ev: MouseEvent) => { 1652 if (!this.loadTraceCompleted || !this.mouseEventEnable) return; 1653 if (this.isWASDKeyPress()) { 1654 ev.preventDefault(); 1655 ev.stopPropagation(); 1656 return; 1657 } 1658 TraceRow.isUserInteraction = false; 1659 this.rangeSelect.isMouseDown = false; 1660 if ((window as any).isSheetMove) return; 1661 if (this.isMouseInSheet(ev)) return; 1662 this.rangeSelect.mouseUp(ev); 1663 this.timerShaftEL?.documentOnMouseUp(ev); 1664 ev.preventDefault(); 1665 ev.stopPropagation(); 1666 }; 1667 1668 documentOnMouseOut = (ev: MouseEvent) => { 1669 if (!this.loadTraceCompleted) return; 1670 TraceRow.isUserInteraction = false; 1671 if (this.isMouseInSheet(ev)) return; 1672 if (ev.offsetX > this.timerShaftEL!.canvas!.offsetLeft) { 1673 this.rangeSelect.mouseOut(ev); 1674 this.timerShaftEL?.documentOnMouseOut(ev); 1675 } 1676 }; 1677 1678 private keyPressMap: Map<string, boolean> = new Map([ 1679 ['w', false], 1680 ['s', false], 1681 ['a', false], 1682 ['d', false], 1683 ['f', false], 1684 ]); 1685 documentOnKeyPress = (ev: KeyboardEvent) => { 1686 if (!this.loadTraceCompleted) return; 1687 let keyPress = ev.key.toLocaleLowerCase(); 1688 TraceRow.isUserInteraction = true; 1689 if (this.isMousePointInSheet) { 1690 return; 1691 } 1692 this.observerScrollHeightEnable = false; 1693 if (this.keyboardEnable) { 1694 if (keyPress == 'm') { 1695 this.slicestime = this.setSLiceMark(ev.shiftKey); 1696 // 设置currentPane可以显示,并且修改调色板颜色和刚刚绘制的帽子颜色保持一致。 1697 this.traceSheetEL = this.shadowRoot?.querySelector('.trace-sheet'); 1698 let currentPane = this.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current'); 1699 if (this.slicestime) { 1700 currentPane?.setCurrentSlicesTime(this.slicestime); 1701 } 1702 // 显示对应的面板信息 1703 this.timerShaftEL!.selectionList.forEach((selection, index) => { 1704 if (this.timerShaftEL!.selectionList.length - 1 == index) { 1705 // 把最新添加的 SelectionParam 对象设置为可以显示当前面板 1706 selection.isCurrentPane = true; 1707 this.traceSheetEL?.rangeSelect(selection); 1708 } else { 1709 // 其他 SelectionParam 对象设置为不显示当前面板 1710 selection.isCurrentPane = false; 1711 } 1712 }); 1713 } 1714 if (keyPress === 'f') { 1715 // 设置当前的slicesTime 1716 this.setCurrentSlicesTime(); 1717 } 1718 let keyPressWASD = keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd'; 1719 if (keyPressWASD) { 1720 this.keyPressMap.set(keyPress, true); 1721 this.hoverFlag = null; 1722 } 1723 this.timerShaftEL!.documentOnKeyPress(ev, this.currentSlicesTime); 1724 if (keyPress === 'f') { 1725 this.verticalScrollToRow(); 1726 } 1727 } else { 1728 this.stopWASD(); 1729 } 1730 }; 1731 1732 verticalScrollToRow() { 1733 if (this.currentRow) { 1734 this.currentRow.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); 1735 } 1736 } 1737 1738 setCurrentSlicesTime() { 1739 if (CpuStruct.selectCpuStruct) { 1740 if (CpuStruct.selectCpuStruct.startTime && CpuStruct.selectCpuStruct.dur) { 1741 this.currentSlicesTime.startTime = CpuStruct.selectCpuStruct.startTime; 1742 this.currentSlicesTime.endTime = CpuStruct.selectCpuStruct.startTime + CpuStruct.selectCpuStruct.dur; 1743 } 1744 } else if (ThreadStruct.selectThreadStruct) { 1745 if (ThreadStruct.selectThreadStruct.startTime && ThreadStruct.selectThreadStruct.dur) { 1746 this.currentSlicesTime.startTime = ThreadStruct.selectThreadStruct.startTime; 1747 this.currentSlicesTime.endTime = 1748 ThreadStruct.selectThreadStruct.startTime + ThreadStruct.selectThreadStruct.dur; 1749 } 1750 } else if (FuncStruct.selectFuncStruct) { 1751 if (FuncStruct.selectFuncStruct.startTs && FuncStruct.selectFuncStruct.dur) { 1752 this.currentSlicesTime.startTime = FuncStruct.selectFuncStruct.startTs; 1753 this.currentSlicesTime.endTime = FuncStruct.selectFuncStruct.startTs + FuncStruct.selectFuncStruct.dur; 1754 } 1755 } else if (IrqStruct.selectIrqStruct) { 1756 if (IrqStruct.selectIrqStruct.startNS && IrqStruct.selectIrqStruct.dur) { 1757 this.currentSlicesTime.startTime = IrqStruct.selectIrqStruct.startNS; 1758 this.currentSlicesTime.endTime = IrqStruct.selectIrqStruct.startNS + IrqStruct.selectIrqStruct.dur; 1759 } 1760 } else if (TraceRow.rangeSelectObject) { 1761 if (TraceRow.rangeSelectObject.startNS && TraceRow.rangeSelectObject.endNS) { 1762 this.currentSlicesTime.startTime = TraceRow.rangeSelectObject.startNS; 1763 this.currentSlicesTime.endTime = TraceRow.rangeSelectObject.endNS; 1764 } 1765 } else if (JankStruct.selectJankStruct) { 1766 if (JankStruct.selectJankStruct.ts && JankStruct.selectJankStruct.dur) { 1767 this.currentSlicesTime.startTime = JankStruct.selectJankStruct.ts; 1768 this.currentSlicesTime.endTime = JankStruct.selectJankStruct.ts + JankStruct.selectJankStruct.dur; 1769 } 1770 } else { 1771 this.currentSlicesTime.startTime = 0; 1772 this.currentSlicesTime.endTime = 0; 1773 } 1774 } 1775 1776 setSLiceMark(shiftKey: boolean): SlicesTime | null | undefined { 1777 if (CpuStruct.selectCpuStruct) { 1778 this.slicestime = this.timerShaftEL?.setSlicesMark( 1779 CpuStruct.selectCpuStruct.startTime || 0, 1780 (CpuStruct.selectCpuStruct.startTime || 0) + (CpuStruct.selectCpuStruct.dur || 0), 1781 shiftKey 1782 ); 1783 } else if (ThreadStruct.selectThreadStruct) { 1784 this.slicestime = this.timerShaftEL?.setSlicesMark( 1785 ThreadStruct.selectThreadStruct.startTime || 0, 1786 (ThreadStruct.selectThreadStruct.startTime || 0) + (ThreadStruct.selectThreadStruct.dur || 0), 1787 shiftKey 1788 ); 1789 } else if (FuncStruct.selectFuncStruct) { 1790 this.slicestime = this.timerShaftEL?.setSlicesMark( 1791 FuncStruct.selectFuncStruct.startTs || 0, 1792 (FuncStruct.selectFuncStruct.startTs || 0) + (FuncStruct.selectFuncStruct.dur || 0), 1793 shiftKey 1794 ); 1795 } else if (IrqStruct.selectIrqStruct) { 1796 this.slicestime = this.timerShaftEL?.setSlicesMark( 1797 IrqStruct.selectIrqStruct.startNS || 0, 1798 (IrqStruct.selectIrqStruct.startNS || 0) + (IrqStruct.selectIrqStruct.dur || 0), 1799 shiftKey 1800 ); 1801 } else if (TraceRow.rangeSelectObject) { 1802 this.slicestime = this.timerShaftEL?.setSlicesMark( 1803 TraceRow.rangeSelectObject.startNS || 0, 1804 TraceRow.rangeSelectObject.endNS || 0, 1805 shiftKey 1806 ); 1807 } else if (JankStruct.selectJankStruct) { 1808 this.slicestime = this.timerShaftEL?.setSlicesMark( 1809 JankStruct.selectJankStruct.ts || 0, 1810 (JankStruct.selectJankStruct.ts || 0) + (JankStruct.selectJankStruct.dur || 0), 1811 shiftKey 1812 ); 1813 } else if (AppStartupStruct.selectStartupStruct) { 1814 this.slicestime = this.timerShaftEL?.setSlicesMark( 1815 AppStartupStruct.selectStartupStruct.startTs || 0, 1816 (AppStartupStruct.selectStartupStruct.startTs || 0) + (AppStartupStruct.selectStartupStruct.dur || 0), 1817 shiftKey 1818 ); 1819 } else if (SoStruct.selectSoStruct) { 1820 this.slicestime = this.timerShaftEL?.setSlicesMark( 1821 SoStruct.selectSoStruct.startTs || 0, 1822 (SoStruct.selectSoStruct.startTs || 0) + (SoStruct.selectSoStruct.dur || 0), 1823 shiftKey 1824 ); 1825 } else if (FrameAnimationStruct.selectFrameAnimationStruct) { 1826 this.timerShaftEL?.setSlicesMark( 1827 FrameAnimationStruct.selectFrameAnimationStruct.ts || 0, 1828 (FrameAnimationStruct.selectFrameAnimationStruct.ts || 0) + 1829 (FrameAnimationStruct.selectFrameAnimationStruct.dur || 0) 1830 ); 1831 } else if (JsCpuProfilerStruct.selectJsCpuProfilerStruct) { 1832 this.timerShaftEL?.setSlicesMark( 1833 JsCpuProfilerStruct.selectJsCpuProfilerStruct.startTime || 0, 1834 (JsCpuProfilerStruct.selectJsCpuProfilerStruct.startTime || 0) + 1835 (JsCpuProfilerStruct.selectJsCpuProfilerStruct.totalTime || 0) 1836 ); 1837 } else { 1838 this.slicestime = this.timerShaftEL?.setSlicesMark(); 1839 } 1840 return this.slicestime; 1841 } 1842 1843 stopWASD = () => { 1844 setTimeout(() => { 1845 for (let key of this.keyPressMap.keys()) { 1846 if (this.keyPressMap.get(key)) { 1847 this.timerShaftEL?.stopWASD({ key: key }); 1848 this.keyPressMap.set(key, false); 1849 } 1850 } 1851 }, 100); 1852 }; 1853 1854 documentOnKeyUp = (ev: KeyboardEvent) => { 1855 if (!this.loadTraceCompleted) return; 1856 let keyPress = ev.key.toLocaleLowerCase(); 1857 if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') { 1858 this.keyPressMap.set(keyPress, false); 1859 } 1860 TraceRow.isUserInteraction = false; 1861 this.observerScrollHeightEnable = false; 1862 this.keyboardEnable && this.timerShaftEL!.documentOnKeyUp(ev); 1863 if (ev.code == 'Enter') { 1864 if (ev.shiftKey) { 1865 this.dispatchEvent( 1866 new CustomEvent('previous-data', { 1867 detail: {}, 1868 composed: false, 1869 }) 1870 ); 1871 } else { 1872 this.dispatchEvent( 1873 new CustomEvent('next-data', { 1874 detail: {}, 1875 composed: false, 1876 }) 1877 ); 1878 } 1879 } 1880 }; 1881 1882 isMouseInSheet = (ev: MouseEvent) => { 1883 this.isMousePointInSheet = 1884 this.traceSheetEL?.getAttribute('mode') != 'hidden' && 1885 ev.offsetX > this.traceSheetEL!.offsetLeft && 1886 ev.offsetY > this.traceSheetEL!.offsetTop; 1887 return this.isMousePointInSheet; 1888 }; 1889 1890 favoriteChangeHandler = (row: TraceRow<any>) => { 1891 info('favoriteChangeHandler', row.frame, row.offsetTop, row.offsetHeight); 1892 }; 1893 1894 verticalScrollHandler = (row: TraceRow<any>) => { 1895 row.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); 1896 }; 1897 selectChangeHandler = (rows: Array<TraceRow<any>>) => { 1898 this.isSelectClick = true; 1899 this.rangeSelect.rangeTraceRow = rows; 1900 let changeTraceRows: Array<TraceRow<any>> = []; 1901 if (this.rangeTraceRow!.length < rows.length) { 1902 rows!.forEach((currentTraceRow: TraceRow<any>) => { 1903 let changeFilter = this.rangeTraceRow!.filter( 1904 (prevTraceRow: TraceRow<any>) => prevTraceRow === currentTraceRow 1905 ); 1906 if (changeFilter.length < 1) { 1907 changeTraceRows.push(currentTraceRow); 1908 } 1909 }); 1910 if (changeTraceRows.length > 0) { 1911 changeTraceRows!.forEach((changeTraceRow: TraceRow<any>) => { 1912 let pointEvent = this.createPointEvent(changeTraceRow); 1913 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 1914 action: 'trace_row', 1915 event: pointEvent, 1916 }); 1917 }); 1918 } 1919 } 1920 this.rangeTraceRow = rows; 1921 this.rangeSelect.selectHandler?.(this.rangeSelect.rangeTraceRow, false); 1922 }; 1923 inFavoriteArea: boolean | undefined; 1924 documentOnMouseMove = (ev: MouseEvent) => { 1925 if (!this.loadTraceCompleted || (window as any).flagInputFocus || !this.mouseEventEnable) return; 1926 if (this.isWASDKeyPress()) { 1927 this.hoverFlag = null; 1928 ev.preventDefault(); 1929 return; 1930 } 1931 this.inFavoriteArea = this.favoriteRowsEL?.containPoint(ev); 1932 if ((window as any).isSheetMove) return; 1933 if (this.isMouseInSheet(ev)) { 1934 this.hoverStructNull(); 1935 return; 1936 } 1937 let isMouseInTimeShaft = this.timerShaftEL?.containPoint(ev); 1938 if (isMouseInTimeShaft) { 1939 this.tipEL!.style.display = 'none'; 1940 this.hoverStructNull(); 1941 } 1942 let rows = this.visibleRows; 1943 if (this.timerShaftEL?.isScaling()) { 1944 return; 1945 } 1946 this.timerShaftEL?.documentOnMouseMove(ev); 1947 if (isMouseInTimeShaft) { 1948 return; 1949 } 1950 this.rangeSelect.mouseMove(rows, ev); 1951 if (this.rangeSelect.isMouseDown) { 1952 this.refreshCanvas(true); 1953 } else { 1954 if (!this.rowsPaneEL!.containPoint(ev, { left: 248 })) { 1955 this.tipEL!.style.display = 'none'; 1956 this.hoverStructNull(); 1957 } 1958 rows 1959 .filter((it) => it.focusContain(ev, this.inFavoriteArea!) && it.collect === this.inFavoriteArea) 1960 .filter((it) => { 1961 if (it.collect) { 1962 return true; 1963 } else { 1964 return ( 1965 it.getBoundingClientRect().bottom + it.getBoundingClientRect().height > 1966 this.favoriteRowsEL!.getBoundingClientRect().bottom 1967 ); 1968 } 1969 }) 1970 .forEach((tr) => { 1971 if (this.currentRowType != tr.rowType) { 1972 this.hoverStructNull(); 1973 this.tipEL!.style.display = 'none'; 1974 this.currentRowType = tr.rowType || ''; 1975 } 1976 if (tr.rowType == TraceRow.ROW_TYPE_CPU) { 1977 CpuStruct.hoverCpuStruct = undefined; 1978 for (let re of tr.dataListCache) { 1979 if (re.frame && isFrameContainPoint(re.frame, tr.hoverX, tr.hoverY)) { 1980 CpuStruct.hoverCpuStruct = re; 1981 break; 1982 } 1983 } 1984 } else { 1985 CpuStruct.hoverCpuStruct = undefined; 1986 } 1987 tr.focusHandler?.(ev); 1988 }); 1989 requestAnimationFrame(() => this.refreshCanvas(true)); 1990 } 1991 }; 1992 1993 hoverStructNull() { 1994 CpuStruct.hoverCpuStruct = undefined; 1995 CpuFreqStruct.hoverCpuFreqStruct = undefined; 1996 ThreadStruct.hoverThreadStruct = undefined; 1997 FuncStruct.hoverFuncStruct = undefined; 1998 HiPerfCpuStruct.hoverStruct = undefined; 1999 HiPerfProcessStruct.hoverStruct = undefined; 2000 HiPerfThreadStruct.hoverStruct = undefined; 2001 HiPerfEventStruct.hoverStruct = undefined; 2002 HiPerfReportStruct.hoverStruct = undefined; 2003 CpuStateStruct.hoverStateStruct = undefined; 2004 CpuAbilityMonitorStruct.hoverCpuAbilityStruct = undefined; 2005 DiskAbilityMonitorStruct.hoverDiskAbilityStruct = undefined; 2006 MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = undefined; 2007 NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = undefined; 2008 CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = undefined; 2009 FpsStruct.hoverFpsStruct = undefined; 2010 ClockStruct.hoverClockStruct = undefined; 2011 IrqStruct.hoverIrqStruct = undefined; 2012 HeapStruct.hoverHeapStruct = undefined; 2013 JankStruct.hoverJankStruct = undefined; 2014 AppStartupStruct.hoverStartupStruct = undefined; 2015 SoStruct.hoverSoStruct = undefined; 2016 HeapSnapshotStruct.hoverSnapshotStruct = undefined; 2017 FrameAnimationStruct.hoverFrameAnimationStruct = undefined; 2018 FrameDynamicStruct.hoverFrameDynamicStruct = undefined; 2019 FrameSpacingStruct.hoverFrameSpacingStruct = undefined; 2020 JsCpuProfilerStruct.hoverJsCpuProfilerStruct = undefined; 2021 SnapshotStruct.hoverSnapshotStruct = undefined; 2022 } 2023 2024 selectStructNull() { 2025 CpuStruct.selectCpuStruct = undefined; 2026 CpuStruct.wakeupBean = null; 2027 CpuFreqStruct.selectCpuFreqStruct = undefined; 2028 ThreadStruct.selectThreadStruct = undefined; 2029 FuncStruct.selectFuncStruct = undefined; 2030 SpHiPerf.selectCpuStruct = undefined; 2031 CpuStateStruct.selectStateStruct = undefined; 2032 CpuFreqLimitsStruct.selectCpuFreqLimitsStruct = undefined; 2033 ClockStruct.selectClockStruct = undefined; 2034 IrqStruct.selectIrqStruct = undefined; 2035 JankStruct.selectJankStruct = undefined; 2036 HeapStruct.selectHeapStruct = undefined; 2037 AppStartupStruct.selectStartupStruct = undefined; 2038 SoStruct.selectSoStruct = undefined; 2039 HeapSnapshotStruct.selectSnapshotStruct = undefined; 2040 FrameSpacingStruct.selectFrameSpacingStruct = undefined; 2041 FrameAnimationStruct.selectFrameAnimationStruct = undefined; 2042 FrameDynamicStruct.selectFrameDynamicStruct = undefined; 2043 JsCpuProfilerStruct.selectJsCpuProfilerStruct = undefined; 2044 SnapshotStruct.selectSnapshotStruct = undefined; 2045 } 2046 2047 isWASDKeyPress() { 2048 return ( 2049 this.keyPressMap.get('w') || this.keyPressMap.get('a') || this.keyPressMap.get('d') || this.keyPressMap.get('s') 2050 ); 2051 } 2052 2053 documentOnClick = (ev: MouseEvent) => { 2054 if (!this.loadTraceCompleted) return; 2055 if (this.isWASDKeyPress()) { 2056 this.hoverFlag = null; 2057 ev.preventDefault(); 2058 ev.stopPropagation(); 2059 return; 2060 } 2061 if ((window as any).isSheetMove) return; 2062 if (this.isMouseInSheet(ev)) return; 2063 if ((window as any).isPackUpTable) { 2064 (window as any).isPackUpTable = false; 2065 return; 2066 } 2067 let x = ev.offsetX - this.timerShaftEL!.canvas!.offsetLeft; 2068 let y = ev.offsetY; 2069 if (this.timerShaftEL?.getRangeRuler()?.frame.contains(x, y)) { 2070 this.clickEmptyArea(); 2071 return; 2072 } 2073 if (this.rangeSelect.isDrag()) { 2074 return; 2075 } 2076 if ( 2077 this.timerShaftEL!.sportRuler!.frame.contains(x, y) && 2078 x > (TraceRow.rangeSelectObject?.startX || 0) && 2079 x < (TraceRow.rangeSelectObject?.endX || 0) 2080 ) { 2081 } else { 2082 let inFavoriteArea = this.favoriteRowsEL?.containPoint(ev); 2083 let rows = this.visibleRows.filter((it) => it.focusContain(ev, inFavoriteArea!) && it.collect == inFavoriteArea); 2084 if (JankStruct.delJankLineFlag) { 2085 this.removeLinkLinesByBusinessType('janks'); 2086 } 2087 if (rows && rows[0] && this.traceRowClickJudgmentConditions.get(rows[0]!.rowType!)?.()) { 2088 this.onClickHandler(rows[0]!.rowType!, rows[0]); 2089 this.documentOnMouseMove(ev); 2090 } else { 2091 this.clickEmptyArea(); 2092 } 2093 } 2094 ev.preventDefault(); 2095 }; 2096 2097 clickEmptyArea() { 2098 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => { 2099 it.checkType = '-1'; 2100 it.rangeSelect = false; 2101 }); 2102 this.rangeSelect.rangeTraceRow = []; 2103 TraceRow.rangeSelectObject = undefined; 2104 this.selectStructNull(); 2105 this.wakeupListNull(); 2106 this.observerScrollHeightEnable = false; 2107 this.selectFlag = null; 2108 this.timerShaftEL?.removeTriangle('inverted'); 2109 this.traceSheetEL?.setAttribute('mode', 'hidden'); 2110 this.removeLinkLinesByBusinessType('task'); 2111 this.refreshCanvas(true); 2112 JankStruct.delJankLineFlag = true; 2113 } 2114 2115 //泳道图点击判定条件 2116 private traceRowClickJudgmentConditions: Map<string, () => boolean> = new Map<string, () => boolean>([ 2117 [TraceRow.ROW_TYPE_CPU, () => CpuStruct.hoverCpuStruct !== null && CpuStruct.hoverCpuStruct !== undefined], 2118 [ 2119 TraceRow.ROW_TYPE_THREAD, 2120 () => ThreadStruct.hoverThreadStruct !== null && ThreadStruct.hoverThreadStruct !== undefined, 2121 ], 2122 [TraceRow.ROW_TYPE_FUNC, () => FuncStruct.hoverFuncStruct !== null && FuncStruct.hoverFuncStruct !== undefined], 2123 [ 2124 TraceRow.ROW_TYPE_CPU_FREQ, 2125 () => CpuFreqStruct.hoverCpuFreqStruct !== null && CpuFreqStruct.hoverCpuFreqStruct !== undefined, 2126 ], 2127 [ 2128 TraceRow.ROW_TYPE_CPU_STATE, 2129 () => CpuStateStruct.hoverStateStruct !== null && CpuStateStruct.hoverStateStruct !== undefined, 2130 ], 2131 [ 2132 TraceRow.ROW_TYPE_CPU_FREQ_LIMIT, 2133 () => 2134 CpuFreqLimitsStruct.selectCpuFreqLimitsStruct !== null && 2135 CpuFreqLimitsStruct.selectCpuFreqLimitsStruct !== undefined, 2136 ], 2137 [ 2138 TraceRow.ROW_TYPE_CLOCK, 2139 () => ClockStruct.hoverClockStruct !== null && ClockStruct.hoverClockStruct !== undefined, 2140 ], 2141 [TraceRow.ROW_TYPE_IRQ, () => IrqStruct.hoverIrqStruct !== null && IrqStruct.hoverIrqStruct !== undefined], 2142 [ 2143 TraceRow.ROW_TYPE_APP_STARTUP, 2144 () => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined, 2145 ], 2146 [TraceRow.ROW_TYPE_STATIC_INIT, () => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined], 2147 [TraceRow.ROW_TYPE_JANK, () => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined], 2148 [TraceRow.ROW_TYPE_HEAP, () => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined], 2149 [ 2150 TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL, 2151 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2152 ], 2153 [ 2154 TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW, 2155 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2156 ], 2157 [ 2158 TraceRow.ROW_TYPE_HEAP_SNAPSHOT, 2159 () => HeapSnapshotStruct.hoverSnapshotStruct !== null && HeapSnapshotStruct.hoverSnapshotStruct !== undefined, 2160 ], 2161 [ 2162 TraceRow.ROW_TYPE_FRAME_ANIMATION, 2163 () => 2164 FrameAnimationStruct.hoverFrameAnimationStruct !== null && 2165 FrameAnimationStruct.hoverFrameAnimationStruct !== undefined, 2166 ], 2167 [ 2168 TraceRow.ROW_TYPE_FRAME_DYNAMIC, 2169 () => 2170 FrameDynamicStruct.hoverFrameDynamicStruct !== null && FrameDynamicStruct.hoverFrameDynamicStruct !== undefined, 2171 ], 2172 [ 2173 TraceRow.ROW_TYPE_FRAME_SPACING, 2174 () => 2175 FrameSpacingStruct.hoverFrameSpacingStruct !== null && FrameSpacingStruct.hoverFrameSpacingStruct !== undefined, 2176 ], 2177 [ 2178 TraceRow.ROW_TYPE_JS_CPU_PROFILER, 2179 () => 2180 JsCpuProfilerStruct.hoverJsCpuProfilerStruct !== null && 2181 JsCpuProfilerStruct.hoverJsCpuProfilerStruct !== undefined, 2182 ], 2183 [ 2184 TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY, 2185 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2186 ], 2187 [ 2188 TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY, 2189 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2190 ], 2191 [ 2192 TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM, 2193 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2194 ], 2195 [ 2196 TraceRow.ROW_TYPE_PURGEABLE_PIN_VM, 2197 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2198 ], 2199 [ 2200 TraceRow.ROW_TYPE_DMA_ABILITY, 2201 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2202 ], 2203 [ 2204 TraceRow.ROW_TYPE_DMA_VMTRACKER, 2205 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2206 ], 2207 [ 2208 TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY, 2209 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2210 ], 2211 [ 2212 TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER, 2213 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2214 ], 2215 [ 2216 TraceRow.ROW_TYPE_VMTRACKER_SHM, 2217 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2218 ], 2219 [ 2220 TraceRow.ROW_TYPE_VM_TRACKER_SMAPS, 2221 () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined, 2222 ], 2223 ]); 2224 2225 onClickHandler(clickRowType: string, row?: TraceRow<any>) { 2226 if (row) { 2227 this.currentRow = row; 2228 this.setAttribute('clickRow', clickRowType); 2229 this.setAttribute('rowName', row.name!); 2230 this.setAttribute('rowId', row.rowId!); 2231 } 2232 if (!this.loadTraceCompleted) return; 2233 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => (it.rangeSelect = false)); 2234 this.selectStructNull(); 2235 this.wakeupListNull(); 2236 let threadClickHandler: any; 2237 let threadClickPreviousHandler: any; 2238 let threadClickNextHandler: any; 2239 let cpuClickHandler: any; 2240 let jankClickHandler: any; 2241 let snapshotClickHandler: any; 2242 let scrollToFuncHandler: any; 2243 threadClickHandler = (d: ThreadStruct) => { 2244 this.observerScrollHeightEnable = false; 2245 this.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true); 2246 let cpuRow = this.shadowRoot?.querySelectorAll<TraceRow<CpuStruct>>( 2247 `trace-row[row-id='${d.cpu}'][row-type='cpu-data']` 2248 )[0]; 2249 let findEntry = cpuRow!.dataList!.find((dat: any) => dat.startTime === d.startTime); 2250 if ( 2251 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || 2252 findEntry!.startTime! > TraceRow.range!.endNS 2253 ) { 2254 this.timerShaftEL?.setRangeNS( 2255 findEntry!.startTime! - findEntry!.dur! * 2, 2256 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 2257 ); 2258 } 2259 this.hoverStructNull(); 2260 this.selectStructNull(); 2261 this.wakeupListNull(); 2262 CpuStruct.hoverCpuStruct = findEntry; 2263 CpuStruct.selectCpuStruct = findEntry; 2264 this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 2265 this.traceSheetEL?.displayCpuData( 2266 CpuStruct.selectCpuStruct!, 2267 (wakeUpBean) => { 2268 CpuStruct.wakeupBean = wakeUpBean; 2269 this.refreshCanvas(true); 2270 }, 2271 cpuClickHandler 2272 ); 2273 }; 2274 2275 threadClickPreviousHandler = (d: ThreadStruct) => { 2276 this.observerScrollHeightEnable = false; 2277 let threadRow = this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>( 2278 `trace-row[row-id='${d.tid}'][row-type='thread']` 2279 ); 2280 threadRow?.dataList.forEach((item, index) => { 2281 if (item === d && index !== 0) { 2282 let findEntry = threadRow?.dataList[index - 1]; 2283 this.hoverStructNull(); 2284 this.selectStructNull(); 2285 this.wakeupListNull(); 2286 ThreadStruct.hoverThreadStruct = findEntry; 2287 ThreadStruct.selectThreadStruct = findEntry; 2288 this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 2289 this.traceSheetEL?.displayThreadData( 2290 ThreadStruct.selectThreadStruct!, 2291 threadClickHandler, 2292 cpuClickHandler, 2293 threadClickPreviousHandler, 2294 threadClickNextHandler 2295 ); 2296 } 2297 }); 2298 }; 2299 threadClickNextHandler = (d: ThreadStruct) => { 2300 this.observerScrollHeightEnable = false; 2301 let threadRow = this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>( 2302 `trace-row[row-id='${d.tid}'][row-type='thread']` 2303 ); 2304 let findEntry = threadRow?.dataList.find((dat: any) => dat.startTime === d.startTime! + d.dur!); 2305 this.hoverStructNull(); 2306 this.selectStructNull(); 2307 this.wakeupListNull(); 2308 ThreadStruct.hoverThreadStruct = findEntry; 2309 ThreadStruct.selectThreadStruct = findEntry; 2310 this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 2311 this.traceSheetEL?.displayThreadData( 2312 ThreadStruct.selectThreadStruct!, 2313 threadClickHandler, 2314 cpuClickHandler, 2315 threadClickPreviousHandler, 2316 threadClickNextHandler 2317 ); 2318 }; 2319 cpuClickHandler = (d: CpuStruct) => { 2320 let traceRow = this.shadowRoot?.querySelector<TraceRow<any>>( 2321 `trace-row[row-id='${d.processId}'][row-type='process']` 2322 ); 2323 if (traceRow) { 2324 traceRow.expansion = true; 2325 } 2326 this.observerScrollHeightEnable = true; 2327 let threadRow = this.shadowRoot?.querySelectorAll<TraceRow<ThreadStruct>>( 2328 `trace-row[row-id='${d.tid}'][row-type='thread']` 2329 )[0]; 2330 let task = () => { 2331 if (threadRow) { 2332 let findEntry = threadRow!.dataList!.find((dat) => dat.startTime === d.startTime); 2333 if ( 2334 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || 2335 findEntry!.startTime! > TraceRow.range!.endNS 2336 ) { 2337 this.timerShaftEL?.setRangeNS( 2338 findEntry!.startTime! - findEntry!.dur! * 2, 2339 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 2340 ); 2341 } 2342 this.hoverStructNull(); 2343 this.selectStructNull(); 2344 this.wakeupListNull(); 2345 ThreadStruct.hoverThreadStruct = findEntry; 2346 ThreadStruct.selectThreadStruct = findEntry; 2347 this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 2348 this.traceSheetEL?.displayThreadData( 2349 ThreadStruct.selectThreadStruct!, 2350 threadClickHandler, 2351 cpuClickHandler, 2352 threadClickPreviousHandler, 2353 threadClickNextHandler 2354 ); 2355 this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 2356 } 2357 }; 2358 if (threadRow) { 2359 this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'process', false); 2360 this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 2361 if (threadRow!.isComplete) { 2362 task(); 2363 } else { 2364 threadRow!.onComplete = task; 2365 } 2366 } 2367 }; 2368 2369 jankClickHandler = (d: any) => { 2370 this.observerScrollHeightEnable = true; 2371 let jankRowParent: any; 2372 if (d.rowId === 'actual frameTime') { 2373 jankRowParent = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(`trace-row[row-id='frameTime']`); 2374 } else { 2375 jankRowParent = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(`trace-row[row-id='${d.pid}']`); 2376 } 2377 // jankRowParent!.expansion = true; 2378 let jankRow: any; 2379 jankRowParent.childrenList.forEach((item: TraceRow<JankStruct>) => { 2380 if (item.rowId === `${d.rowId}` && item.rowType === 'janks') { 2381 jankRow = item; 2382 } 2383 }); 2384 let task = () => { 2385 if (jankRow) { 2386 JankStruct.selectJankStructList.length = 0; 2387 let findJankEntry = jankRow!.dataList!.find((dat: any) => dat.name == d.name && dat.pid == d.pid); 2388 if (findJankEntry) { 2389 if ( 2390 findJankEntry!.ts! + findJankEntry!.dur! < TraceRow.range!.startNS || 2391 findJankEntry!.ts! > TraceRow.range!.endNS 2392 ) { 2393 this.timerShaftEL?.setRangeNS( 2394 findJankEntry!.ts! - findJankEntry!.dur! * 2, 2395 findJankEntry!.ts! + findJankEntry!.dur! + findJankEntry!.dur! * 2 2396 ); 2397 } 2398 this.hoverStructNull(); 2399 this.selectStructNull(); 2400 this.wakeupListNull(); 2401 JankStruct.hoverJankStruct = findJankEntry; 2402 JankStruct.selectJankStruct = findJankEntry; 2403 this.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted'); 2404 this.traceSheetEL?.displayJankData( 2405 JankStruct.selectJankStruct!, 2406 (datas) => { 2407 this.removeLinkLinesByBusinessType('janks'); 2408 // 绘制跟自己关联的线 2409 datas.forEach((data) => { 2410 let endParentRow = this.shadowRoot?.querySelector<TraceRow<any>>( 2411 `trace-row[row-id='${data.pid}'][folder]` 2412 ); 2413 this.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data); 2414 }); 2415 }, 2416 jankClickHandler 2417 ); 2418 } 2419 this.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, true); 2420 } 2421 }; 2422 if (jankRow) { 2423 this.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, false); 2424 } 2425 task(); 2426 }; 2427 2428 scrollToFuncHandler = (funcStract: any) => { 2429 this.observerScrollHeightEnable = true; 2430 this.moveRangeToCenter(funcStract.startTime!, funcStract.dur!); 2431 this.scrollToActFunc(funcStract, false); 2432 }; 2433 2434 snapshotClickHandler = (d: HeapSnapshotStruct) => { 2435 this.observerScrollHeightEnable = true; 2436 let snapshotRow = this.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>( 2437 `trace-row[row-id='heapsnapshot']` 2438 ); 2439 let task = () => { 2440 if (snapshotRow) { 2441 let findEntry = snapshotRow!.dataList!.find((dat) => dat.startTs === d.startTs); 2442 this.hoverStructNull(); 2443 this.selectStructNull(); 2444 this.wakeupListNull(); 2445 HeapSnapshotStruct.hoverSnapshotStruct = findEntry; 2446 HeapSnapshotStruct.selectSnapshotStruct = findEntry; 2447 } 2448 }; 2449 if (snapshotRow) { 2450 if (snapshotRow!.isComplete) { 2451 task(); 2452 } else { 2453 snapshotRow!.onComplete = task; 2454 } 2455 } 2456 }; 2457 if (clickRowType === TraceRow.ROW_TYPE_CPU && CpuStruct.hoverCpuStruct) { 2458 CpuStruct.selectCpuStruct = CpuStruct.hoverCpuStruct; 2459 this.timerShaftEL?.drawTriangle(CpuStruct.selectCpuStruct!.startTime || 0, 'inverted'); 2460 this.traceSheetEL?.displayCpuData( 2461 CpuStruct.selectCpuStruct, 2462 (wakeUpBean) => { 2463 CpuStruct.wakeupBean = wakeUpBean; 2464 this.refreshCanvas(false); 2465 }, 2466 cpuClickHandler 2467 ); 2468 this.timerShaftEL?.modifyFlagList(undefined); 2469 } else if (clickRowType === TraceRow.ROW_TYPE_THREAD && ThreadStruct.hoverThreadStruct) { 2470 ThreadStruct.selectThreadStruct = ThreadStruct.hoverThreadStruct; 2471 this.timerShaftEL?.drawTriangle(ThreadStruct.selectThreadStruct!.startTime || 0, 'inverted'); 2472 this.traceSheetEL?.displayThreadData( 2473 ThreadStruct.selectThreadStruct, 2474 threadClickHandler, 2475 cpuClickHandler, 2476 threadClickPreviousHandler, 2477 threadClickNextHandler 2478 ); 2479 this.timerShaftEL?.modifyFlagList(undefined); 2480 } else if (clickRowType === TraceRow.ROW_TYPE_FUNC && FuncStruct.hoverFuncStruct) { 2481 TabPaneTaskFrames.TaskArray = []; 2482 this.removeLinkLinesByBusinessType('task'); 2483 FuncStruct.selectFuncStruct = FuncStruct.hoverFuncStruct; 2484 let hoverFuncStruct = FuncStruct.hoverFuncStruct; 2485 this.timerShaftEL?.drawTriangle(FuncStruct.selectFuncStruct!.startTs || 0, 'inverted'); 2486 FuncStruct.selectFuncStruct = hoverFuncStruct; 2487 let flagConfig = FlagsConfig.getFlagsConfig('TaskPool'); 2488 let showTabArray: Array<string> = ['current-selection']; 2489 if (flagConfig!.TaskPool === 'Enabled') { 2490 if (FuncStruct.selectFuncStruct !== undefined && FuncStruct.selectFuncStruct.funName !== undefined) { 2491 if (FuncStruct.selectFuncStruct.funName.indexOf('H:Task ') >= 0) { 2492 showTabArray.push('box-task-frames'); 2493 this.drawTaskPollLine(row); 2494 } 2495 } 2496 } 2497 this.traceSheetEL?.displayFuncData(showTabArray, FuncStruct.selectFuncStruct, scrollToFuncHandler); 2498 this.timerShaftEL?.modifyFlagList(undefined); 2499 } else if (clickRowType === TraceRow.ROW_TYPE_CPU_FREQ && CpuFreqStruct.hoverCpuFreqStruct) { 2500 CpuFreqStruct.selectCpuFreqStruct = CpuFreqStruct.hoverCpuFreqStruct; 2501 this.traceSheetEL?.displayFreqData(); 2502 this.timerShaftEL?.modifyFlagList(undefined); 2503 } else if (clickRowType === TraceRow.ROW_TYPE_CPU_STATE && CpuStateStruct.hoverStateStruct) { 2504 CpuStateStruct.selectStateStruct = CpuStateStruct.hoverStateStruct; 2505 this.traceSheetEL?.displayCpuStateData(); 2506 this.timerShaftEL?.modifyFlagList(undefined); 2507 } else if (clickRowType === TraceRow.ROW_TYPE_CPU_FREQ_LIMIT && CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct) { 2508 CpuFreqLimitsStruct.selectCpuFreqLimitsStruct = CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct; 2509 this.traceSheetEL?.displayFreqLimitData(); 2510 this.timerShaftEL?.modifyFlagList(undefined); 2511 } else if (clickRowType === TraceRow.ROW_TYPE_CLOCK && ClockStruct.hoverClockStruct) { 2512 ClockStruct.selectClockStruct = ClockStruct.hoverClockStruct; 2513 this.traceSheetEL?.displayClockData(ClockStruct.selectClockStruct); 2514 this.timerShaftEL?.modifyFlagList(undefined); 2515 } else if (clickRowType === TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL && SnapshotStruct.hoverSnapshotStruct) { 2516 let gpuDumpTotalRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2517 `trace-row[row-id='Skia Gpu Dump Total']` 2518 ); 2519 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2520 this.traceSheetEL?.displayGpuSelectedData( 2521 'total', 2522 SnapshotStruct.selectSnapshotStruct.startNs, 2523 gpuDumpTotalRow!.dataList 2524 ); 2525 this.timerShaftEL?.modifyFlagList(undefined); 2526 } else if (clickRowType === TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW && SnapshotStruct.hoverSnapshotStruct) { 2527 let gpuDumpWindowRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2528 `trace-row[row-id='Skia Gpu Dump Window']` 2529 ); 2530 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2531 this.traceSheetEL?.displayGpuSelectedData( 2532 'window', 2533 SnapshotStruct.selectSnapshotStruct.startNs, 2534 gpuDumpWindowRow!.dataList 2535 ); 2536 this.timerShaftEL?.modifyFlagList(undefined); 2537 } else if (clickRowType === TraceRow.ROW_TYPE_IRQ && IrqStruct.hoverIrqStruct) { 2538 IrqStruct.selectIrqStruct = IrqStruct.hoverIrqStruct; 2539 this.traceSheetEL?.displayIrqData(IrqStruct.selectIrqStruct); 2540 this.timerShaftEL?.modifyFlagList(undefined); 2541 } else if ( 2542 clickRowType === TraceRow.ROW_TYPE_HEAP && 2543 row && 2544 row.getAttribute('heap-type') === 'native_hook_statistic' && 2545 HeapStruct.hoverHeapStruct 2546 ) { 2547 HeapStruct.selectHeapStruct = HeapStruct.hoverHeapStruct; 2548 this.traceSheetEL?.displayNativeHookData(HeapStruct.selectHeapStruct, row.rowId!); 2549 this.timerShaftEL?.modifyFlagList(undefined); 2550 } else if (clickRowType === TraceRow.ROW_TYPE_JANK && JankStruct.hoverJankStruct) { 2551 JankStruct.selectJankStructList.length = 0; 2552 this.removeLinkLinesByBusinessType('janks'); 2553 JankStruct.selectJankStruct = JankStruct.hoverJankStruct; 2554 this.timerShaftEL?.drawTriangle(JankStruct.selectJankStruct!.ts || 0, 'inverted'); 2555 this.traceSheetEL?.displayJankData( 2556 JankStruct.selectJankStruct, 2557 (datas) => { 2558 datas.forEach((data) => { 2559 let endParentRow; 2560 if (data.frame_type == 'frameTime') { 2561 endParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 2562 `trace-row[row-id='frameTime'][row-type='janks']` 2563 ); 2564 } else { 2565 endParentRow = this.shadowRoot?.querySelector<TraceRow<any>>(`trace-row[row-id='${data.pid}'][folder]`); 2566 } 2567 this.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data); 2568 }); 2569 }, 2570 jankClickHandler 2571 ); 2572 } else if (clickRowType === TraceRow.ROW_TYPE_HEAP_SNAPSHOT && HeapSnapshotStruct.hoverSnapshotStruct) { 2573 let snapshotRow = this.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>( 2574 `trace-row[row-id='heapsnapshot']` 2575 ); 2576 HeapSnapshotStruct.selectSnapshotStruct = HeapSnapshotStruct.hoverSnapshotStruct; 2577 this.traceSheetEL?.displaySnapshotData( 2578 HeapSnapshotStruct.selectSnapshotStruct!, 2579 snapshotRow!.dataList, 2580 snapshotClickHandler 2581 ); 2582 } else if (clickRowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER && JsCpuProfilerStruct.hoverJsCpuProfilerStruct) { 2583 JsCpuProfilerStruct.selectJsCpuProfilerStruct = JsCpuProfilerStruct.hoverJsCpuProfilerStruct; 2584 let selectStruct = JsCpuProfilerStruct.selectJsCpuProfilerStruct; 2585 let dataArr: Array<JsCpuProfilerChartFrame> = []; 2586 let parentIdArr: Array<number> = []; 2587 let that = this; 2588 getTopJsCpuProfilerStruct(selectStruct.parentId); 2589 function getTopJsCpuProfilerStruct(parentId: number) { 2590 if (parentId === -1 && selectStruct.parentId === -1) { 2591 // 点击的函数是第一层,直接设置其children的isSelect为true,不用重新算totalTime 2592 let data = that.chartManager!.arkTsChart.chartFrameMap.get(selectStruct!.id); 2593 if (data && dataArr.length === 0) { 2594 let copyData = JSON.parse(JSON.stringify(data)); 2595 setSelectChildrenState(copyData); 2596 dataArr.push(copyData); 2597 } 2598 } else { 2599 let parent = that.chartManager!.arkTsChart.chartFrameMap.get(parentId); 2600 if (parent) { 2601 parentIdArr.push(parent.id); 2602 getTopJsCpuProfilerStruct(parent.parentId!); 2603 if (parent.parentId === -1 && dataArr.length === 0) { 2604 let data = that.chartManager!.arkTsChart.chartFrameMap.get(parent.id); 2605 let copyParent = JSON.parse(JSON.stringify(data)); 2606 copyParent.totalTime = selectStruct.totalTime; 2607 copyParent.selfTime = 0; 2608 // depth为0的isSelect改为true 2609 copyParent.isSelect = true; 2610 if (copyParent.children.length > 0) { 2611 getSelectStruct(copyParent); 2612 } 2613 dataArr.push(copyParent); 2614 } 2615 } 2616 } 2617 } 2618 2619 function getSelectStruct(data: JsCpuProfilerChartFrame) { 2620 for (let child of data.children) { 2621 if (child.id === selectStruct!.id) { 2622 // 将点击的函数的children的isSelect改为true 2623 setSelectChildrenState(child); 2624 } else { 2625 getSelectStruct(child); 2626 } 2627 if (parentIdArr.includes(child.id)) { 2628 child.isSelect = true; 2629 child.totalTime = selectStruct.totalTime; 2630 child.selfTime = 0; 2631 } 2632 } 2633 } 2634 2635 function setSelectChildrenState(data: JsCpuProfilerChartFrame) { 2636 data.isSelect = true; 2637 if (data.children.length > 0) { 2638 for (let child of data.children) { 2639 setSelectChildrenState(child); 2640 } 2641 } 2642 } 2643 that.traceSheetEL?.displayJsProfilerData(dataArr); 2644 } else if (clickRowType === TraceRow.ROW_TYPE_APP_STARTUP && AppStartupStruct.hoverStartupStruct) { 2645 AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct; 2646 this.traceSheetEL?.displayStartupData(AppStartupStruct.selectStartupStruct, scrollToFuncHandler); 2647 this.timerShaftEL?.modifyFlagList(undefined); 2648 } else if (clickRowType === TraceRow.ROW_TYPE_STATIC_INIT && SoStruct.hoverSoStruct) { 2649 SoStruct.selectSoStruct = SoStruct.hoverSoStruct; 2650 this.traceSheetEL?.displayStaticInitData(SoStruct.selectSoStruct, scrollToFuncHandler); 2651 this.timerShaftEL?.modifyFlagList(undefined); 2652 } else if (clickRowType === TraceRow.ROW_TYPE_FRAME_ANIMATION && FrameAnimationStruct.hoverFrameAnimationStruct) { 2653 FrameAnimationStruct.selectFrameAnimationStruct = FrameAnimationStruct.hoverFrameAnimationStruct; 2654 this.traceSheetEL?.displayFrameAnimationData(FrameAnimationStruct.selectFrameAnimationStruct); 2655 this.timerShaftEL?.modifyFlagList(undefined); 2656 } else if (clickRowType === TraceRow.ROW_TYPE_FRAME_DYNAMIC && FrameDynamicStruct.hoverFrameDynamicStruct) { 2657 FrameDynamicStruct.selectFrameDynamicStruct = FrameDynamicStruct.hoverFrameDynamicStruct; 2658 this.traceSheetEL?.displayFrameDynamicData(row!, FrameDynamicStruct.selectFrameDynamicStruct); 2659 this.timerShaftEL?.modifyFlagList(undefined); 2660 } else if (clickRowType === TraceRow.ROW_TYPE_FRAME_SPACING && FrameSpacingStruct.hoverFrameSpacingStruct) { 2661 FrameSpacingStruct.selectFrameSpacingStruct = FrameSpacingStruct.hoverFrameSpacingStruct; 2662 this.traceSheetEL?.displayFrameSpacingData(FrameSpacingStruct.selectFrameSpacingStruct); 2663 this.timerShaftEL?.modifyFlagList(undefined); 2664 } else if (clickRowType === TraceRow.ROW_TYPE_VM_TRACKER_SMAPS && SnapshotStruct.hoverSnapshotStruct) { 2665 let smapsRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='Dirty']`); 2666 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2667 this.traceSheetEL?.displaySmapsData(SnapshotStruct.selectSnapshotStruct!, smapsRow!.dataList); 2668 } else if (clickRowType === TraceRow.ROW_TYPE_VMTRACKER_SHM && SnapshotStruct.hoverSnapshotStruct) { 2669 let shmRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='SHM']`); 2670 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2671 this.traceSheetEL?.displayShmData(SnapshotStruct.selectSnapshotStruct!, shmRow!.dataList); 2672 } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY && SnapshotStruct.hoverSnapshotStruct) { 2673 let totalAbilityRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2674 `trace-row[row-id='System Purgeable Total']` 2675 ); 2676 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2677 this.traceSheetEL?.displayPurgTotalAbilityData(SnapshotStruct.hoverSnapshotStruct, totalAbilityRow!.dataList); 2678 } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY && SnapshotStruct.hoverSnapshotStruct) { 2679 let pinAbilityRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2680 `trace-row[row-id='System Purgeable Pin']` 2681 ); 2682 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2683 this.traceSheetEL?.displayPurgPinAbilityData(SnapshotStruct.hoverSnapshotStruct, pinAbilityRow!.dataList); 2684 } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM && SnapshotStruct.hoverSnapshotStruct) { 2685 let totalVMRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='Purgeable Total']`); 2686 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2687 this.traceSheetEL?.displayPurgTotalVMData(SnapshotStruct.hoverSnapshotStruct, totalVMRow!.dataList); 2688 } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_VM && SnapshotStruct.hoverSnapshotStruct) { 2689 let pinVMRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='Purgeable Pin']`); 2690 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2691 this.traceSheetEL?.displayPurgPinVMData(SnapshotStruct.hoverSnapshotStruct, pinVMRow!.dataList); 2692 } else if (clickRowType === TraceRow.ROW_TYPE_DMA_ABILITY && SnapshotStruct.hoverSnapshotStruct) { 2693 let dmaAbilityRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2694 `trace-row[row-id='abilityMonitorDma']` 2695 ); 2696 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2697 this.traceSheetEL?.displayDmaAbility(SnapshotStruct.selectSnapshotStruct.startNs, dmaAbilityRow!.dataList); 2698 } else if (clickRowType === TraceRow.ROW_TYPE_DMA_VMTRACKER && SnapshotStruct.hoverSnapshotStruct) { 2699 let dmaVmTracker = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2700 `trace-row[row-type='dma-vmTracker']` 2701 ); 2702 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2703 this.traceSheetEL?.displayDmaVmTracker(SnapshotStruct.selectSnapshotStruct.startNs, dmaVmTracker!.dataList); 2704 } else if (clickRowType === TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY && SnapshotStruct.hoverSnapshotStruct) { 2705 let gpuMemoryAbilityMonitor = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2706 `trace-row[row-id='abilityMonitorGpuMemory']` 2707 ); 2708 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2709 this.traceSheetEL?.displayGpuMemoryAbility( 2710 SnapshotStruct.selectSnapshotStruct.startNs, 2711 gpuMemoryAbilityMonitor!.dataList 2712 ); 2713 } else if (clickRowType === TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER && SnapshotStruct.hoverSnapshotStruct) { 2714 let gpuMemoryVmTracker = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>( 2715 `trace-row[row-id='Skia Gpu Memory']` 2716 ); 2717 SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct; 2718 this.traceSheetEL?.displayGpuMemoryVmTracker( 2719 SnapshotStruct.selectSnapshotStruct.startNs, 2720 gpuMemoryVmTracker!.dataList 2721 ); 2722 } else { 2723 if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) { 2724 this.removeLinkLinesByBusinessType('janks'); 2725 } 2726 this.observerScrollHeightEnable = false; 2727 this.selectFlag = null; 2728 this.timerShaftEL?.removeTriangle('inverted'); 2729 if (!SportRuler.isMouseInSportRuler) { 2730 this.traceSheetEL?.setAttribute('mode', 'hidden'); 2731 this.refreshCanvas(true); 2732 } 2733 } 2734 if (!JankStruct.selectJankStruct) { 2735 this.removeLinkLinesByBusinessType('janks'); 2736 } 2737 if (row) { 2738 let pointEvent = this.createPointEvent(row); 2739 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 2740 action: 'trace_row', 2741 event: pointEvent, 2742 }); 2743 } 2744 } 2745 2746 makePoint( 2747 ts: number, 2748 dur: number, 2749 translateY: number, 2750 rowStruct: any, 2751 offsetY: number, 2752 business: string, 2753 lineType: LineType, 2754 isRight: boolean 2755 ): PairPoint { 2756 return { 2757 x: ns2xByTimeShaft(ts + dur, this.timerShaftEL!), 2758 y: translateY!, 2759 offsetY: offsetY, 2760 ns: ts + dur, 2761 rowEL: rowStruct!, 2762 isRight: isRight, 2763 business: business, 2764 lineType: lineType, 2765 }; 2766 } 2767 2768 drawTaskPollLine(row?: TraceRow<any>) { 2769 let executeID = TabPaneTaskFrames.getExecuteId(FuncStruct.selectFuncStruct!.funName!); 2770 TabPaneTaskFrames.TaskArray.push(FuncStruct.selectFuncStruct!); 2771 if (!row) { 2772 return; 2773 } 2774 if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task Perform:') >= 0) { 2775 TabPaneTaskFrames.IsShowConcurrency = true; 2776 queryBySelectExecute(executeID, FuncStruct.selectFuncStruct!.itid!).then((res) => { 2777 if (res.length === 1) { 2778 let allocationRowId = res[0].tid; 2779 let selectRow = this.shadowRoot?.querySelector<TraceRow<FuncStruct>>( 2780 `trace-row[row-id='${allocationRowId}'][row-type=\'func\']` 2781 ); 2782 selectRow!.dataList.forEach((value) => { 2783 // allocation to execute 2784 if (value.id === res[0].allocation_task_row) { 2785 TabPaneTaskFrames.TaskArray.push(value); 2786 this.addPointPair( 2787 this.makePoint( 2788 value.startTs!, 2789 0, 2790 selectRow?.translateY!, 2791 selectRow, 2792 (value.depth! + 0.5) * 20, 2793 'task', 2794 LineType.bezierCurve, 2795 true 2796 ), 2797 this.makePoint( 2798 FuncStruct.selectFuncStruct!.startTs!, 2799 0, 2800 row?.translateY!, 2801 row, 2802 (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20, 2803 'task', 2804 LineType.bezierCurve, 2805 true 2806 ) 2807 ); 2808 } 2809 // execute to return 2810 if (value.id === res[0].return_task_row) { 2811 TabPaneTaskFrames.TaskArray.push(value); 2812 this.addPointPair( 2813 this.makePoint( 2814 FuncStruct.selectFuncStruct!.startTs!, 2815 FuncStruct.selectFuncStruct!.dur!, 2816 row?.translateY!, 2817 row, 2818 (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20, 2819 'task', 2820 LineType.bezierCurve, 2821 false 2822 ), 2823 this.makePoint( 2824 value.startTs!, 2825 value.dur!, 2826 selectRow?.translateY!, 2827 selectRow, 2828 (value.depth! + 0.5) * 20, 2829 'task', 2830 LineType.bezierCurve, 2831 false 2832 ) 2833 ); 2834 } 2835 }); 2836 this.refreshCanvas(true); 2837 } 2838 }); 2839 } else { 2840 TabPaneTaskFrames.IsShowConcurrency = false; 2841 queryBySelectAllocationOrReturn(executeID, FuncStruct.selectFuncStruct!.itid!).then((res) => { 2842 if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task Allocation:') >= 0 && res.length > 0) { 2843 let executeRow = this.shadowRoot?.querySelector<TraceRow<FuncStruct>>( 2844 `trace-row[row-id='${res[0].tid}'][row-type='func']` 2845 ); 2846 let endStruct: FuncStruct; 2847 row!.dataList.forEach((value) => { 2848 if (value.id === res[0].return_task_row) { 2849 TabPaneTaskFrames.TaskArray.push(value); 2850 endStruct = value; 2851 } 2852 }); 2853 if (!executeRow) { 2854 return; 2855 } 2856 executeRow!.dataList.forEach((value) => { 2857 if (value.id === res[0].execute_task_row) { 2858 TabPaneTaskFrames.TaskArray.push(value); 2859 this.addPointPair( 2860 this.makePoint( 2861 FuncStruct.selectFuncStruct!.startTs!, 2862 0, 2863 row?.translateY!, 2864 row, 2865 (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20, 2866 'task', 2867 LineType.bezierCurve, 2868 true 2869 ), 2870 this.makePoint( 2871 value.startTs!, 2872 0, 2873 executeRow?.translateY!, 2874 executeRow, 2875 (value.depth! + 0.5) * 20, 2876 'task', 2877 LineType.bezierCurve, 2878 true 2879 ) 2880 ); 2881 if (endStruct) { 2882 this.addPointPair( 2883 this.makePoint( 2884 value.startTs!, 2885 value.dur!, 2886 executeRow?.translateY!, 2887 executeRow, 2888 (value.depth! + 0.5) * 20, 2889 'task', 2890 LineType.bezierCurve, 2891 false 2892 ), 2893 this.makePoint( 2894 endStruct.startTs!, 2895 endStruct.dur!, 2896 row?.translateY!, 2897 row, 2898 (endStruct.depth! + 0.5) * 20, 2899 'task', 2900 LineType.bezierCurve, 2901 false 2902 ) 2903 ); 2904 } 2905 } 2906 }); 2907 } else if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task PerformTask End:') >= 0) { 2908 let executeRow = this.shadowRoot?.querySelector<TraceRow<FuncStruct>>( 2909 `trace-row[row-id='${res[0].tid}'][row-type='func']` 2910 ); 2911 TabPaneTaskFrames.TaskArray.push(FuncStruct.selectFuncStruct!); 2912 let startStruct: FuncStruct; 2913 row!.dataList.forEach((value) => { 2914 if (value.id === res[0].allocation_task_row) { 2915 TabPaneTaskFrames.TaskArray.push(value); 2916 startStruct = value; 2917 } 2918 }); 2919 executeRow!.dataList.forEach((value) => { 2920 if (value.id === res[0].execute_task_row) { 2921 TabPaneTaskFrames.TaskArray.push(value); 2922 this.addPointPair( 2923 this.makePoint( 2924 startStruct!.startTs!, 2925 0, 2926 row?.translateY!, 2927 row, 2928 (startStruct!.depth! + 0.5) * 20, 2929 'task', 2930 LineType.bezierCurve, 2931 true 2932 ), 2933 this.makePoint( 2934 value.startTs!, 2935 0, 2936 executeRow?.translateY!, 2937 executeRow, 2938 (value.depth! + 0.5) * 20, 2939 'task', 2940 LineType.bezierCurve, 2941 true 2942 ) 2943 ); 2944 this.addPointPair( 2945 this.makePoint( 2946 value.startTs!, 2947 value.dur!, 2948 executeRow?.translateY!, 2949 executeRow, 2950 (value.depth! + 0.5) * 20, 2951 'task', 2952 LineType.bezierCurve, 2953 false 2954 ), 2955 this.makePoint( 2956 FuncStruct.selectFuncStruct!.startTs!, 2957 FuncStruct.selectFuncStruct!.dur!, 2958 row?.translateY!, 2959 row, 2960 (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20, 2961 'task', 2962 LineType.bezierCurve, 2963 false 2964 ) 2965 ); 2966 } 2967 }); 2968 } 2969 this.refreshCanvas(true); 2970 }); 2971 } 2972 } 2973 drawJankLine(endParentRow: any, selectJankStruct: JankStruct, data: any) { 2974 let collectList = this.favoriteRowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[collect-type]`) || []; 2975 let startRow: any; 2976 if (selectJankStruct == undefined || selectJankStruct == null) { 2977 return; 2978 } 2979 if (selectJankStruct.frame_type == 'frameTime') { 2980 startRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 2981 "trace-row[row-id='actual frameTime'][row-type='janks']" 2982 ); 2983 } else { 2984 startRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 2985 `trace-row[row-id='${`${selectJankStruct?.type}-${selectJankStruct?.pid}`}'][row-type='janks']` 2986 ); 2987 } 2988 2989 function collectionHasJank(jankRow: any): boolean { 2990 for (let item of collectList!) { 2991 if (item.rowId === jankRow.rowId && item.rowType === jankRow.rowType) { 2992 return false; 2993 } 2994 } 2995 return true; 2996 } 2997 2998 if (endParentRow) { 2999 //终点的父泳道过滤出选中的Struct 3000 let endRowStruct: any; 3001 //泳道展开的情况,查找endRowStruct 3002 if (data.frame_type == 'frameTime') { 3003 endRowStruct = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 3004 "trace-row[row-id='actual frameTime'][row-type='janks']" 3005 ); 3006 } else { 3007 endRowStruct = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 3008 `trace-row[row-id='${`${data.type}-${data.pid}`}'][row-type='janks']` 3009 ); 3010 } 3011 //泳道未展开的情况,查找endRowStruct 3012 if (!endRowStruct) { 3013 if (data.frame_type == 'frameTime') { 3014 endParentRow.childrenList.forEach((item: TraceRow<JankStruct>) => { 3015 if (item.rowId === 'actual frameTime' && item.rowType === 'janks') { 3016 endRowStruct = item; 3017 } 3018 }); 3019 //frameTime未展开 3020 if (!endRowStruct) { 3021 endParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 3022 "trace-row[row-id='frameTime'][folder]" 3023 ); 3024 endParentRow?.childrenList?.forEach((item: TraceRow<JankStruct>) => { 3025 if (item.rowId === 'actual frameTime' && item.rowType === 'janks') { 3026 endRowStruct = item; 3027 } 3028 }); 3029 } 3030 } else { 3031 endParentRow.childrenList.forEach((item: TraceRow<JankStruct>) => { 3032 if (item.rowId === `${data.type}-${data.pid}` && item.rowType === 'janks') { 3033 endRowStruct = item; 3034 } 3035 }); 3036 } 3037 } 3038 if (endRowStruct) { 3039 let findJankEntry = endRowStruct!.dataList!.find((dat: any) => dat.name == data.name && dat.pid == data.pid); 3040 //连线规则:frametimeline的头----app的头,app的尾----renderservice的头 3041 let tts: number = 0; 3042 if (findJankEntry) { 3043 if (selectJankStruct.frame_type == 'app') { 3044 tts = 3045 findJankEntry.frame_type == 'frameTime' 3046 ? selectJankStruct.ts! 3047 : selectJankStruct.ts! + selectJankStruct.dur!; 3048 let startParentRow: any; 3049 // startRow为子泳道,子泳道不存在,使用父泳道 3050 if (startRow) { 3051 startParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 3052 `trace-row[row-id='${startRow.rowParentId}'][folder]` 3053 ); 3054 } else { 3055 startRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 3056 `trace-row[row-id='${selectJankStruct?.pid}'][folder]` 3057 ); 3058 } 3059 let endY = endRowStruct!.translateY! + 20 * (findJankEntry!.depth! + 0.5); 3060 let endRowEl = endRowStruct; 3061 let endOffSetY = 20 * (findJankEntry!.depth! + 0.5); 3062 let expansionFlag = collectionHasJank(endRowStruct); 3063 if (!endParentRow.expansion && expansionFlag) { 3064 endY = endParentRow!.translateY! + 10 * (findJankEntry!.depth! + 0.5); 3065 endRowEl = endParentRow; 3066 endOffSetY = 10 * (findJankEntry!.depth! + 0.5); 3067 } 3068 let startY = startRow!.translateY! + 20 * (selectJankStruct!.depth! + 0.5); 3069 let startRowEl = startRow; 3070 let startOffSetY = 20 * (selectJankStruct!.depth! + 0.5); 3071 expansionFlag = collectionHasJank(startRow); 3072 if (startParentRow && !startParentRow.expansion && expansionFlag) { 3073 startY = startParentRow!.translateY! + 10 * (selectJankStruct!.depth! + 0.5); 3074 startRowEl = startParentRow; 3075 startOffSetY = 10 * (selectJankStruct!.depth! + 0.5); 3076 } 3077 this.addPointPair( 3078 { 3079 x: ns2xByTimeShaft(tts, this.timerShaftEL!), 3080 y: startY, 3081 offsetY: startOffSetY, 3082 ns: tts, 3083 rowEL: startRowEl!, 3084 isRight: selectJankStruct.ts == tts, 3085 business: 'janks', 3086 }, 3087 { 3088 x: ns2xByTimeShaft(findJankEntry.ts!, this.timerShaftEL!), 3089 y: endY, 3090 offsetY: endOffSetY, 3091 ns: findJankEntry.ts!, 3092 rowEL: endRowEl, 3093 isRight: true, 3094 business: 'janks', 3095 } 3096 ); 3097 } 3098 if (findJankEntry.frame_type == 'app') { 3099 tts = 3100 selectJankStruct.frame_type == 'frameTime' ? findJankEntry.ts : findJankEntry.ts! + findJankEntry.dur!; 3101 let endY = endRowStruct!.translateY! + 20 * (findJankEntry!.depth! + 0.5); 3102 let endRowEl = endRowStruct; 3103 let endOffSetY = 20 * (findJankEntry!.depth! + 0.5); 3104 let expansionFlag = collectionHasJank(endRowStruct); 3105 if (!endParentRow.expansion && expansionFlag) { 3106 endY = endParentRow!.translateY! + 10 * (findJankEntry!.depth! + 0.5); 3107 endRowEl = endParentRow; 3108 endOffSetY = 10 * (findJankEntry!.depth! + 0.5); 3109 } 3110 let startY = startRow!.translateY! + 20 * (selectJankStruct!.depth! + 0.5); 3111 let startRowEl = startRow; 3112 expansionFlag = collectionHasJank(startRow); 3113 let startOffsetY = 20 * (selectJankStruct!.depth! + 0.5); 3114 let startParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>( 3115 `trace-row[row-id='${startRow.rowParentId}'][folder]` 3116 ); 3117 if (startParentRow && !startParentRow.expansion && expansionFlag) { 3118 startY = startParentRow!.translateY! + 10 * (selectJankStruct!.depth! + 0.5); 3119 startRowEl = startParentRow; 3120 startOffsetY = 10 * (selectJankStruct!.depth! + 0.5); 3121 } 3122 this.addPointPair( 3123 { 3124 x: ns2xByTimeShaft(selectJankStruct.ts!, this.timerShaftEL!), 3125 y: startY, 3126 offsetY: startOffsetY, 3127 ns: selectJankStruct.ts!, 3128 rowEL: startRowEl!, 3129 isRight: true, 3130 business: 'janks', 3131 }, 3132 { 3133 x: ns2xByTimeShaft(tts, this.timerShaftEL!), 3134 y: endY, 3135 offsetY: endOffSetY, 3136 ns: tts, 3137 rowEL: endRowEl!, 3138 isRight: selectJankStruct.ts == tts, 3139 business: 'janks', 3140 } 3141 ); 3142 } 3143 if (data.children.length >= 1) { 3144 let endP; 3145 if (data.children[0].frame_type == 'frameTime') { 3146 endP = this.shadowRoot?.querySelector<TraceRow<any>>("trace-row[row-id='frameTime']"); 3147 } else { 3148 endP = this.shadowRoot?.querySelector<TraceRow<any>>( 3149 `trace-row[row-id='${data.children[0].pid}'][folder]` 3150 ); 3151 } 3152 this.drawJankLine(endP, findJankEntry, data.children[0]); 3153 } 3154 this.refreshCanvas(true); 3155 } 3156 } 3157 } 3158 } 3159 3160 myMouseMove = (ev: MouseEvent) => { 3161 if (ev.ctrlKey) { 3162 ev.preventDefault(); 3163 SpSystemTrace.offsetMouse = ev.clientX - SpSystemTrace.mouseCurrentPosition; 3164 let eventA = new KeyboardEvent('keypress', { 3165 key: 'a', 3166 code: '65', 3167 keyCode: 65, 3168 }); 3169 let eventD = new KeyboardEvent('keypress', { 3170 key: 'd', 3171 code: '68', 3172 keyCode: 68, 3173 }); 3174 if (ev.button == 0) { 3175 if (SpSystemTrace.offsetMouse < 0 && SpSystemTrace.moveable) { 3176 // 向右拖动,则泳道图右移 3177 this.timerShaftEL!.documentOnKeyPress(eventD); 3178 setTimeout(() => { 3179 this.timerShaftEL!.documentOnKeyUp(eventD); 3180 }, 350); 3181 } 3182 if (SpSystemTrace.offsetMouse > 0 && SpSystemTrace.moveable) { 3183 // 向左拖动,则泳道图左移 3184 this.timerShaftEL!.documentOnKeyPress(eventA); 3185 setTimeout(() => { 3186 this.timerShaftEL!.documentOnKeyUp(eventA); 3187 }, 350); 3188 } 3189 } 3190 SpSystemTrace.moveable = false; 3191 } 3192 }; 3193 3194 connectedCallback() { 3195 this.initPointToEvent(); 3196 /** 3197 * 监听时间轴区间变化 3198 */ 3199 this.timerShaftEL!.rangeChangeHandler = this.timerShaftELRangeChange; 3200 this.timerShaftEL!.rangeClickHandler = this.timerShaftELRangeClick; 3201 this.timerShaftEL!.flagChangeHandler = this.timerShaftELFlagChange; 3202 this.timerShaftEL!.flagClickHandler = this.timerShaftELFlagClickHandler; 3203 /** 3204 * 监听rowsEL的滚动时间,刷新可见区域的trace-row组件的时间区间(将触发trace-row组件重绘) 3205 */ 3206 this.rowsPaneEL?.addEventListener('scroll', this.rowsElOnScroll, { 3207 passive: true, 3208 }); 3209 this.favoriteRowsEL?.addEventListener('scroll', this.favoriteRowsElOnScroll, { passive: true }); 3210 /** 3211 * 监听document的mousemove事件 坐标通过换算后找到当前鼠标所在的trace-row组件,将坐标传入 3212 */ 3213 this.addEventListener('mousemove', this.documentOnMouseMove); 3214 this.addEventListener('click', this.documentOnClick); 3215 this.addEventListener('mousedown', this.documentOnMouseDown); 3216 this.addEventListener('mouseup', this.documentOnMouseUp); 3217 this.addEventListener('mouseout', this.documentOnMouseOut); 3218 3219 document.addEventListener('keypress', this.documentOnKeyPress); 3220 document.addEventListener('keyup', this.documentOnKeyUp); 3221 document.addEventListener('contextmenu', this.onContextMenuHandler); 3222 3223 /** 3224 * 获取并保存鼠标当前的x轴坐标位置,配合ctrl+鼠标左键拖动完成泳道图的左移或右移 3225 */ 3226 this.addEventListener( 3227 'mousedown', 3228 (e) => { 3229 if (e.ctrlKey) { 3230 e.preventDefault(); 3231 this.removeEventListener('mousemove', this.documentOnMouseMove); 3232 this.removeEventListener('click', this.documentOnClick); 3233 this.removeEventListener('mousedown', this.documentOnMouseDown); 3234 this.removeEventListener('mouseup', this.documentOnMouseUp); 3235 this.style.cursor = 'move'; 3236 SpSystemTrace.moveable = true; 3237 SpSystemTrace.mouseCurrentPosition = e.clientX; 3238 } 3239 }, 3240 { passive: false } 3241 ); 3242 /** 3243 * ctrl+鼠标移动,实现泳道图左移或者右移。 3244 */ 3245 this.addEventListener('mousemove', (ev) => throttle(this.myMouseMove, 350, ev)(), { passive: false }); 3246 3247 this.addEventListener( 3248 'mouseup', 3249 (e) => { 3250 if (e.ctrlKey) { 3251 e.preventDefault(); 3252 SpSystemTrace.offsetMouse = 0; 3253 SpSystemTrace.mouseCurrentPosition = 0; 3254 SpSystemTrace.moveable = false; 3255 this.style.cursor = 'default'; 3256 this.addEventListener('mousemove', this.documentOnMouseMove); 3257 this.addEventListener('click', this.documentOnClick); 3258 this.addEventListener('mousedown', this.documentOnMouseDown); 3259 this.addEventListener('mouseup', this.documentOnMouseUp); 3260 } 3261 }, 3262 { passive: false } 3263 ); 3264 3265 /** 3266 * 泳道图中添加ctrl+鼠标滚轮事件,对泳道图进行放大缩小。 3267 * 鼠标滚轮事件转化为键盘事件,keyPress和keyUp两个事件需要配合使用, 3268 * 否则泳道图会一直放大或一直缩小。 3269 * setTimeout()函数中的时间参数可以控制鼠标滚轮的频率。 3270 */ 3271 document.addEventListener( 3272 'wheel', 3273 (e) => { 3274 if (e.ctrlKey) { 3275 if (e.deltaY > 0) { 3276 e.preventDefault(); 3277 e.stopPropagation(); 3278 let eventS = new KeyboardEvent('keypress', { 3279 key: 's', 3280 code: '83', 3281 keyCode: 83, 3282 }); 3283 this.timerShaftEL!.documentOnKeyPress(eventS); 3284 setTimeout(() => { 3285 this.timerShaftEL!.documentOnKeyUp(eventS); 3286 }, 200); 3287 } 3288 if (e.deltaY < 0) { 3289 e.preventDefault(); 3290 e.stopPropagation(); 3291 let eventW = new KeyboardEvent('keypress', { 3292 key: 'w', 3293 code: '87', 3294 keyCode: 87, 3295 }); 3296 this.timerShaftEL!.documentOnKeyPress(eventW); 3297 setTimeout(() => { 3298 this.timerShaftEL!.documentOnKeyUp(eventW); 3299 }, 200); 3300 } 3301 } 3302 }, 3303 { passive: false } 3304 ); 3305 3306 SpApplication.skinChange2 = (val: boolean) => { 3307 this.timerShaftEL?.render(); 3308 }; 3309 window.subscribe(window.SmartEvent.UI.UploadSOFile, (data) => { 3310 this.chartManager?.importSoFileUpdate().then(() => { 3311 window.publish(window.SmartEvent.UI.Loading, false); 3312 let updateCanvas = this.traceSheetEL?.updateRangeSelect(); 3313 if (updateCanvas) { 3314 this.refreshCanvas(true); 3315 } 3316 }); 3317 }); 3318 window.subscribe(window.SmartEvent.UI.CheckALL, (data) => { 3319 this.favoriteRowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${data.rowId}']`).forEach((it) => { 3320 it.checkType = data.isCheck ? '2' : '0'; 3321 }); 3322 }); 3323 } 3324 3325 scrollToProcess(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true) { 3326 let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowId}'][row-type='${rowType}']`); 3327 if (traceRow?.collect) { 3328 this.favoriteRowsEL!.scroll({ 3329 top: (traceRow?.offsetTop || 0) - this.canvasFavoritePanel!.offsetHeight + (traceRow?.offsetHeight || 0), 3330 left: 0, 3331 behavior: smooth ? 'smooth' : undefined, 3332 }); 3333 } else { 3334 let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowParentId}'][folder]`); 3335 if (row && !row.expansion) { 3336 row.expansion = true; 3337 } 3338 if (traceRow && traceRow.offsetTop >= 0 && traceRow.offsetHeight >= 0) { 3339 this.rowsPaneEL!.scroll({ 3340 top: (traceRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + (traceRow?.offsetHeight || 0), 3341 left: 0, 3342 behavior: smooth ? 'smooth' : undefined, 3343 }); 3344 } 3345 } 3346 } 3347 3348 scrollToDepth(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true, depth: number) { 3349 let rootRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowId}'][row-type='${rowType}']`); 3350 if (rootRow && rootRow!.collect) { 3351 this.favoriteRowsEL!.scroll({ 3352 top: (rootRow?.offsetTop || 0) - this.canvasFavoritePanel!.offsetHeight + (++depth * 20 || 0), 3353 left: 0, 3354 behavior: smooth ? 'smooth' : undefined, 3355 }); 3356 } else { 3357 let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowParentId}'][folder]`); 3358 if (row && !row.expansion) { 3359 row.expansion = true; 3360 } 3361 if (rootRow && rootRow.offsetTop >= 0 && rootRow.offsetHeight >= 0) { 3362 this.rowsPaneEL!.scroll({ 3363 top: (rootRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + (++depth * 20 || 0), 3364 left: 0, 3365 behavior: smooth ? 'smooth' : undefined, 3366 }); 3367 } 3368 } 3369 } 3370 3371 scrollToFunction(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true) { 3372 let condition = `trace-row[row-id='${rowId}'][row-type='${rowType}'][row-parent-id='${rowParentId}']`; 3373 let rootRow = this.shadowRoot!.querySelector<TraceRow<any>>(condition); 3374 if (rootRow?.collect) { 3375 this.favoriteRowsEL!.scroll({ 3376 top: (rootRow?.offsetTop || 0) - this.canvasFavoritePanel!.offsetHeight + (rootRow?.offsetHeight || 0), 3377 left: 0, 3378 behavior: smooth ? 'smooth' : undefined, 3379 }); 3380 } else { 3381 let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowParentId}'][folder]`); 3382 if (row && !row.expansion) { 3383 row.expansion = true; 3384 } 3385 if (rootRow && rootRow.offsetTop >= 0 && rootRow.offsetHeight >= 0) { 3386 this.rowsPaneEL!.scroll({ 3387 top: (rootRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + 20, 3388 left: 0, 3389 behavior: smooth ? 'smooth' : undefined, 3390 }); 3391 } 3392 } 3393 } 3394 3395 rowScrollTo(offset: number, callback: Function) { 3396 const fixedOffset = offset; 3397 const onScroll = () => { 3398 if (this.rowsPaneEL!.scrollTop === fixedOffset) { 3399 this.rowsEL!.removeEventListener('scroll', onScroll); 3400 callback(); 3401 } 3402 }; 3403 3404 this.rowsEL!.addEventListener('scroll', onScroll); 3405 onScroll(); 3406 this.rowsPaneEL!.scrollTo({ 3407 top: offset, 3408 behavior: 'smooth', 3409 }); 3410 } 3411 3412 disconnectedCallback() { 3413 this.timerShaftEL?.removeEventListener('range-change', this.timerShaftELRangeChange); 3414 this.rowsPaneEL?.removeEventListener('scroll', this.rowsElOnScroll); 3415 this.favoriteRowsEL?.removeEventListener('scroll', this.favoriteRowsElOnScroll); 3416 this.removeEventListener('mousemove', this.documentOnMouseMove); 3417 this.removeEventListener('click', this.documentOnClick); 3418 this.removeEventListener('mousedown', this.documentOnMouseDown); 3419 this.removeEventListener('mouseup', this.documentOnMouseUp); 3420 this.removeEventListener('mouseout', this.documentOnMouseOut); 3421 document.removeEventListener('keypress', this.documentOnKeyPress); 3422 document.removeEventListener('keyup', this.documentOnKeyUp); 3423 document.removeEventListener('contextmenu', this.onContextMenuHandler); 3424 window.unsubscribe(window.SmartEvent.UI.SliceMark, this.sliceMarkEventHandler.bind(this)); 3425 } 3426 3427 sliceMarkEventHandler(ev: any) { 3428 SpSystemTrace.sliceRangeMark = ev; 3429 let startNS = ev.timestamp - (window as any).recordStartNS; 3430 let endNS = ev.maxDuration + startNS; 3431 TraceRow.rangeSelectObject = { 3432 startX: 0, 3433 startNS: startNS, 3434 endNS: endNS, 3435 endX: 0, 3436 }; 3437 window.publish(window.SmartEvent.UI.MenuTrace, {}); 3438 window.publish(window.SmartEvent.UI.TimeRange, { 3439 startNS: startNS - ev.maxDuration, 3440 endNS: endNS + ev.maxDuration, 3441 }); 3442 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => { 3443 it.checkType = '-1'; 3444 }); 3445 this.rangeSelect.rangeTraceRow = []; 3446 this.selectStructNull(); 3447 this.wakeupListNull(); 3448 this.traceSheetEL?.setAttribute('mode', 'hidden'); 3449 this.removeLinkLinesByBusinessType('janks'); 3450 TraceRow.range!.refresh = true; 3451 this.refreshCanvas(false); 3452 } 3453 3454 loadDatabaseUrl( 3455 url: string, 3456 progress: Function, 3457 complete?: ((res: { status: boolean; msg: string }) => void) | undefined 3458 ) { 3459 this.observerScrollHeightEnable = false; 3460 this.init({ url: url }, '', progress).then((res) => { 3461 if (complete) { 3462 complete(res); 3463 window.publish(window.SmartEvent.UI.MouseEventEnable, { 3464 mouseEnable: true, 3465 }); 3466 } 3467 }); 3468 } 3469 3470 loadDatabaseArrayBuffer( 3471 buf: ArrayBuffer, 3472 thirdPartyWasmConfigUrl: string, 3473 progress: (name: string, percent: number) => void, 3474 complete?: ((res: { status: boolean; msg: string }) => void) | undefined 3475 ) { 3476 this.observerScrollHeightEnable = false; 3477 this.init({ buf }, thirdPartyWasmConfigUrl, progress).then((res) => { 3478 let scrollTop = this.rowsEL?.scrollTop || 0; 3479 let scrollHeight = this.rowsEL?.clientHeight || 0; 3480 this.rowsEL?.querySelectorAll('trace-row').forEach((it: any) => this.observer.observe(it)); 3481 if (complete) { 3482 complete(res); 3483 window.publish(window.SmartEvent.UI.MouseEventEnable, { 3484 mouseEnable: true, 3485 }); 3486 } 3487 }); 3488 } 3489 3490 search(query: string) { 3491 this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((item) => { 3492 if (query == null || query == undefined || query == '') { 3493 if ( 3494 item.rowType == TraceRow.ROW_TYPE_CPU || 3495 item.rowType == TraceRow.ROW_TYPE_CPU_FREQ || 3496 item.rowType == TraceRow.ROW_TYPE_NATIVE_MEMORY || 3497 item.rowType == TraceRow.ROW_TYPE_FPS || 3498 item.rowType == TraceRow.ROW_TYPE_PROCESS || 3499 item.rowType == TraceRow.ROW_TYPE_CPU_ABILITY || 3500 item.rowType == TraceRow.ROW_TYPE_MEMORY_ABILITY || 3501 item.rowType == TraceRow.ROW_TYPE_DISK_ABILITY || 3502 item.rowType == TraceRow.ROW_TYPE_NETWORK_ABILITY 3503 ) { 3504 item.expansion = false; 3505 item.rowHidden = false; 3506 } else { 3507 item.rowHidden = true; 3508 } 3509 } else { 3510 if (item.name.toLowerCase().indexOf(query.toLowerCase()) >= 0) { 3511 item.rowHidden = false; 3512 } else { 3513 item.rowHidden = true; 3514 } 3515 } 3516 }); 3517 this.visibleRows.forEach((it) => (it.rowHidden = false && it.draw(true))); 3518 } 3519 3520 searchCPU(query: string): Array<CpuStruct> { 3521 let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[scene]`); 3522 let dataAll = `trace-row[row-type='cpu-data']`; 3523 if (traceRow) { 3524 dataAll = `trace-row[row-type='cpu-data'][scene]`; 3525 } 3526 let searchResults: Array<CpuStruct> = []; 3527 this.shadowRoot!.querySelectorAll<TraceRow<any>>(`${dataAll}`).forEach((item) => { 3528 let res = item!.dataList!.filter( 3529 (it) => 3530 (it.name && it.name.indexOf(query) >= 0) || 3531 it.tid == query || 3532 it.processId == query || 3533 (it.processName && it.processName.indexOf(query) >= 0) 3534 ); 3535 searchResults.push(...res); 3536 }); 3537 searchResults.sort((a, b) => (a.startTime || 0) - (b.startTime || 0)); 3538 return searchResults; 3539 } 3540 3541 async searchFunction(cpuList: Array<any>, query: string): Promise<Array<any>> { 3542 let processList: Array<string> = []; 3543 let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[scene]`); 3544 if (traceRow) { 3545 this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='process'][scene]`).forEach((row) => { 3546 processList.push(row.rowId!); 3547 }); 3548 let list = await querySceneSearchFunc(query, processList); 3549 cpuList = cpuList.concat(list); 3550 cpuList.sort((a, b) => (a.startTime || 0) - (b.startTime || 0)); 3551 return cpuList; 3552 } else { 3553 let list = await querySearchFunc(query); 3554 cpuList = cpuList.concat(list); 3555 cpuList.sort((a, b) => (a.startTime || 0) - (b.startTime || 0)); 3556 return cpuList; 3557 } 3558 } 3559 3560 searchSdk(dataList: Array<any>, query: string): Array<any> { 3561 let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[scene]`); 3562 let dataAll = `trace-row[row-type^='sdk']`; 3563 if (traceRow) { 3564 dataAll = `trace-row[row-type^='sdk'][scene]`; 3565 } 3566 let allTraceRow: any = []; 3567 let parentRows = this.shadowRoot!.querySelectorAll<TraceRow<any>>(`${dataAll}`); 3568 parentRows.forEach((parentRow: TraceRow<any>) => { 3569 allTraceRow.push(parentRow); 3570 if (parentRow.childrenList && parentRow.childrenList.length > 0) { 3571 allTraceRow.push(...parentRow.childrenList); 3572 } 3573 }); 3574 allTraceRow.forEach((row: any) => { 3575 if (row!.name.indexOf(query) >= 0) { 3576 let searchSdkBean = new SearchSdkBean(); 3577 searchSdkBean.startTime = TraceRow.range!.startNS; 3578 searchSdkBean.dur = TraceRow.range!.totalNS; 3579 searchSdkBean.name = row.name; 3580 searchSdkBean.rowId = row.rowId; 3581 searchSdkBean.type = 'sdk'; 3582 searchSdkBean.rowType = row.rowType; 3583 searchSdkBean.rowParentId = row.rowParentId; 3584 dataList.push(searchSdkBean); 3585 } 3586 }); 3587 return dataList; 3588 } 3589 3590 searchThreadsAndProcesses(query: string): Array<any> { 3591 let searchResults: Array<any> = []; 3592 this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='thread'][row-type='process']`).forEach((item) => { 3593 if (item!.name.indexOf(query) >= 0) { 3594 let searchBean = new SearchThreadProcessBean(); 3595 searchBean.name = item.name; 3596 searchBean.rowId = item.rowId; 3597 searchBean.type = 'thread||process'; 3598 searchBean.rowType = item.rowType; 3599 searchBean.rowParentId = item.rowParentId; 3600 searchResults.push(searchBean); 3601 } 3602 }); 3603 return searchResults; 3604 } 3605 3606 showStruct(previous: boolean, currentIndex: number, structs: Array<any>) { 3607 if (structs.length == 0) { 3608 return 0; 3609 } 3610 let findIndex = -1; 3611 if (previous) { 3612 for (let i = structs.length - 1; i >= 0; i--) { 3613 let it = structs[i]; 3614 if ( 3615 i < currentIndex && 3616 it.startTime! >= TraceRow.range!.startNS && 3617 it.startTime! + it.dur! <= TraceRow.range!.endNS 3618 ) { 3619 findIndex = i; 3620 break; 3621 } 3622 } 3623 } else { 3624 findIndex = structs.findIndex((it, idx) => { 3625 return ( 3626 idx > currentIndex && 3627 it.startTime! >= TraceRow.range!.startNS && 3628 it.startTime! + it.dur! <= TraceRow.range!.endNS 3629 ); 3630 }); 3631 } 3632 let findEntry: any; 3633 if (findIndex >= 0) { 3634 findEntry = structs[findIndex]; 3635 } else { 3636 if (previous) { 3637 for (let i = structs.length - 1; i >= 0; i--) { 3638 let it = structs[i]; 3639 if (it.startTime! + it.dur! < TraceRow.range!.startNS) { 3640 findIndex = i; 3641 break; 3642 } 3643 } 3644 if (findIndex == -1) { 3645 findIndex = structs.length - 1; 3646 } 3647 } else { 3648 findIndex = structs.findIndex((it) => it.startTime! > TraceRow.range!.endNS); 3649 if (findIndex == -1) { 3650 findIndex = 0; 3651 } 3652 } 3653 findEntry = structs[findIndex]; 3654 } 3655 this.moveRangeToCenter(findEntry.startTime!, findEntry.dur!); 3656 this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row`).forEach((item) => { 3657 item.highlight = false; 3658 }); 3659 if (findEntry.type == 'thread') { 3660 CpuStruct.selectCpuStruct = findEntry; 3661 CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct; 3662 this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => { 3663 item.highlight = item.rowId == `${findEntry.cpu}`; 3664 item.draw(true); 3665 }); 3666 this.scrollToProcess(`${findEntry.cpu}`, '', 'cpu-data', true); 3667 this.onClickHandler(TraceRow.ROW_TYPE_CPU); 3668 } else if (findEntry.type == 'func') { 3669 this.observerScrollHeightEnable = true; 3670 this.scrollToActFunc(findEntry, true); 3671 } else if (findEntry.type == 'thread||process') { 3672 let threadProcessRow = this.rowsEL?.querySelectorAll<TraceRow<ThreadStruct>>('trace-row')[0]; 3673 if (threadProcessRow) { 3674 let filterRow = threadProcessRow.childrenList.filter( 3675 (row) => row.rowId === findEntry.rowId && row.rowId === findEntry.rowType 3676 )[0]; 3677 filterRow!.highlight = true; 3678 this.closeAllExpandRows(findEntry.rowParentId); 3679 this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); 3680 let completeEntry = () => { 3681 let searchEntry = filterRow!.dataList!.find((dat) => dat.startTime === findEntry.startTime); 3682 this.hoverStructNull(); 3683 this.selectStructNull(); 3684 this.wakeupListNull(); 3685 ThreadStruct.hoverThreadStruct = searchEntry; 3686 ThreadStruct.selectThreadStruct = searchEntry; 3687 this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); 3688 }; 3689 if (filterRow!.isComplete) { 3690 completeEntry(); 3691 } else { 3692 filterRow!.onComplete = completeEntry; 3693 } 3694 } 3695 } else if (findEntry.type == 'sdk') { 3696 let parentRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-type='sdk'][folder]`); 3697 if (parentRow) { 3698 let sdkRow = parentRow.childrenList.filter( 3699 (child) => child.rowId === findEntry.rowId && child.rowType === findEntry.rowType 3700 )[0]; 3701 sdkRow!.highlight = true; 3702 } 3703 this.hoverStructNull(); 3704 this.selectStructNull(); 3705 this.wakeupListNull(); 3706 this.onClickHandler(findEntry.rowType!); 3707 this.closeAllExpandRows(findEntry.rowParentId); 3708 this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); 3709 } 3710 this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted'); 3711 return findIndex; 3712 } 3713 3714 scrollToActFunc(funcStract: any, highlight: boolean) { 3715 const toTargetDepth = (entry: any) => { 3716 if (entry) { 3717 this.hoverStructNull(); 3718 this.selectStructNull(); 3719 this.wakeupListNull(); 3720 FuncStruct.hoverFuncStruct = entry; 3721 FuncStruct.selectFuncStruct = entry; 3722 this.onClickHandler(TraceRow.ROW_TYPE_FUNC); 3723 this.scrollToDepth(`${funcRowID}`, `${funcStract.pid}`, funcStract.type, true, entry.depth || 0); 3724 } 3725 }; 3726 let funcRowID = funcStract.cookie == null ? funcStract.tid : `${funcStract.funName}-${funcStract.pid}`; 3727 let targetRow = this.favoriteRowsEL!.querySelector<TraceRow<any>>( 3728 `trace-row[row-id='${funcRowID}'][row-type='func']` 3729 ); 3730 if (targetRow) { 3731 targetRow.highlight = highlight; 3732 //如果目标泳道图在收藏上面,则跳转至收藏 3733 let searchEntry = targetRow!.dataList!.find((dat) => dat.startTs === funcStract.startTime); 3734 toTargetDepth(searchEntry); 3735 return; 3736 } 3737 let parentRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${funcStract.pid}'][folder]`); 3738 if (!parentRow) { 3739 return; 3740 } 3741 let filterRow = parentRow.childrenList.filter((child) => child.rowId == funcRowID && child.rowType == 'func')[0]; 3742 if (filterRow == null) { 3743 let funcRow = this.shadowRoot?.querySelector<TraceRow<any>>(`trace-row[row-id='${funcRowID}'][row-type='func']`); 3744 if (funcRow) { 3745 filterRow = funcRow; 3746 } else { 3747 return; 3748 } 3749 } 3750 filterRow!.highlight = highlight; 3751 if (funcStract.keepOpen !== true) { 3752 this.closeAllExpandRows(funcStract.pid); 3753 } 3754 let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${funcStract.pid}'][folder]`); 3755 if (row && !row.expansion) { 3756 row.expansion = true; 3757 } 3758 const completeEntry = () => { 3759 let entry = filterRow!.dataList!.find((dat) => dat.startTs === funcStract.startTime); 3760 toTargetDepth(entry); 3761 }; 3762 if (filterRow!.isComplete) { 3763 completeEntry(); 3764 } else { 3765 FuncStruct.hoverFuncStruct = funcStract; 3766 FuncStruct.selectFuncStruct = funcStract; 3767 this.onClickHandler(TraceRow.ROW_TYPE_FUNC); 3768 this.scrollToProcess(`${funcStract.tid}`, `${funcStract.pid}`, 'process', false); 3769 this.scrollToFunction(`${funcStract.tid}`, `${funcStract.pid}`, 'func', true); 3770 filterRow!.onComplete = completeEntry; 3771 } 3772 } 3773 3774 closeAllExpandRows(pid: string) { 3775 let expandRows = this.rowsEL?.querySelectorAll<TraceRow<ProcessStruct>>(`trace-row[row-type='process'][expansion]`); 3776 expandRows?.forEach((row) => { 3777 if (row.rowId != pid) { 3778 row.expansion = false; 3779 } 3780 }); 3781 } 3782 3783 moveRangeToCenter(startTime: number, dur: number) { 3784 let startNS = this.timerShaftEL?.getRange()?.startNS || 0; 3785 let endNS = this.timerShaftEL?.getRange()?.endNS || 0; 3786 let harfDur = Math.trunc((endNS - startNS) / 2 - dur / 2); 3787 let leftNs = startTime - harfDur; 3788 let rightNs = startTime + dur + harfDur; 3789 if (startTime - harfDur < 0) { 3790 leftNs = 0; 3791 rightNs += harfDur - startTime; 3792 } 3793 this.timerShaftEL?.setRangeNS(leftNs, rightNs); 3794 TraceRow.range!.refresh = true; 3795 this.refreshCanvas(true); 3796 } 3797 3798 showPreCpuStruct(currentIndex: number, cpuStructs: Array<CpuStruct>): number { 3799 if (cpuStructs.length == 0) { 3800 return 0; 3801 } 3802 let findIndex = -1; 3803 for (let i = cpuStructs.length - 1; i >= 0; i--) { 3804 let it = cpuStructs[i]; 3805 if ( 3806 i < currentIndex && 3807 it.startTime! >= TraceRow.range!.startNS && 3808 it.startTime! + it.dur! <= TraceRow.range!.endNS 3809 ) { 3810 findIndex = i; 3811 break; 3812 } 3813 } 3814 if (findIndex >= 0) { 3815 let findEntry = cpuStructs[findIndex]; 3816 CpuStruct.selectCpuStruct = findEntry; 3817 this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => { 3818 item.highlight = item.rowId == `${findEntry.cpu}`; 3819 item.draw(true); 3820 }); 3821 this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted'); 3822 } else { 3823 for (let i = cpuStructs.length - 1; i >= 0; i--) { 3824 let it = cpuStructs[i]; 3825 if (it.startTime! + it.dur! < TraceRow.range!.startNS) { 3826 findIndex = i; 3827 break; 3828 } 3829 } 3830 let findEntry: CpuStruct; 3831 if (findIndex == -1) { 3832 findIndex = cpuStructs.length - 1; 3833 } 3834 findEntry = cpuStructs[findIndex]; 3835 CpuStruct.selectCpuStruct = findEntry; 3836 let startNS = this.timerShaftEL?.getRange()?.startNS || 0; 3837 let endNS = this.timerShaftEL?.getRange()?.endNS || 0; 3838 let harfDur = Math.trunc((endNS - startNS) / 2 - findEntry.dur! / 2); 3839 this.timerShaftEL?.setRangeNS(findEntry.startTime! - harfDur, findEntry.startTime! + findEntry.dur! + harfDur); 3840 this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => { 3841 item.highlight = item.rowId == `${findEntry.cpu}`; 3842 item.draw(true); 3843 }); 3844 this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted'); 3845 } 3846 CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct; 3847 this.onClickHandler(TraceRow.ROW_TYPE_CPU); 3848 return findIndex; 3849 } 3850 3851 showNextCpuStruct(currentIndex: number, cpuStructs: Array<CpuStruct>): number { 3852 if (cpuStructs.length == 0) { 3853 return 0; 3854 } 3855 let findIndex = cpuStructs.findIndex((it, idx) => { 3856 return ( 3857 idx > currentIndex && 3858 it.startTime! >= TraceRow.range!.startNS && 3859 it.startTime! + it.dur! <= TraceRow.range!.endNS 3860 ); 3861 }); 3862 if (findIndex >= 0) { 3863 let findEntry = cpuStructs[findIndex]; 3864 CpuStruct.selectCpuStruct = findEntry; 3865 this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => { 3866 item.highlight = item.rowId == `${findEntry.cpu}`; 3867 item.draw(true); 3868 }); 3869 this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted'); 3870 } else { 3871 findIndex = cpuStructs.findIndex((it) => it.startTime! > TraceRow.range!.endNS); 3872 let findEntry: CpuStruct; 3873 if (findIndex == -1) { 3874 findIndex = 0; 3875 } 3876 findEntry = cpuStructs[findIndex]; 3877 CpuStruct.selectCpuStruct = findEntry; 3878 let startNS = this.timerShaftEL?.getRange()?.startNS || 0; 3879 let endNS = this.timerShaftEL?.getRange()?.endNS || 0; 3880 let harfDur = Math.trunc((endNS - startNS) / 2 - findEntry.dur! / 2); 3881 this.timerShaftEL?.setRangeNS(findEntry.startTime! - harfDur, findEntry.startTime! + findEntry.dur! + harfDur); 3882 this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => { 3883 item.highlight = item.rowId == `${findEntry.cpu}`; 3884 item.draw(true); 3885 }); 3886 this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted'); 3887 } 3888 CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct; 3889 this.onClickHandler(TraceRow.ROW_TYPE_CPU); 3890 return findIndex; 3891 } 3892 3893 reset(progress: Function | undefined | null) { 3894 this.visibleRows.length = 0; 3895 this.tipEL!.style.display = 'none'; 3896 this.canvasPanelCtx?.clearRect(0, 0, this.canvasPanel!.clientWidth, this.canvasPanel!.offsetHeight); 3897 this.canvasFavoritePanelCtx?.clearRect( 3898 0, 3899 0, 3900 this.canvasFavoritePanel!.clientWidth, 3901 this.canvasFavoritePanel!.clientHeight 3902 ); 3903 this.favoriteRowsEL!.style.height = '0'; 3904 this.canvasFavoritePanel!.style.height = '0'; 3905 this.loadTraceCompleted = false; 3906 this.collectRows = []; 3907 this.visibleRows = []; 3908 TraceRowConfig.allTraceRowList.forEach((it) => { 3909 it.clearMemory(); 3910 }); 3911 TraceRowConfig.allTraceRowList = []; 3912 if (this.favoriteRowsEL) { 3913 this.favoriteRowsEL.querySelectorAll<TraceRow<any>>(`trace-row`).forEach((row) => { 3914 row.clearMemory(); 3915 this.favoriteRowsEL!.removeChild(row); 3916 }); 3917 } 3918 if (this.rowsEL) { 3919 this.rowsEL.querySelectorAll<TraceRow<any>>(`trace-row`).forEach((row) => { 3920 row.clearMemory(); 3921 this.rowsEL!.removeChild(row); 3922 }); 3923 this.rowsEL.innerHTML = ''; 3924 } 3925 this.traceSheetEL?.clearMemory(); 3926 this.spacerEL!.style.height = '0px'; 3927 this.rangeSelect.rangeTraceRow = []; 3928 SpSystemTrace.SDK_CONFIG_MAP = undefined; 3929 SpSystemTrace.sliceRangeMark = undefined; 3930 this.timerShaftEL?.displayCollect(false); 3931 this.timerShaftEL!.collecBtn!.removeAttribute('close'); 3932 CpuStruct.wakeupBean = undefined; 3933 this.selectStructNull(); 3934 this.hoverStructNull(); 3935 this.wakeupListNull(); 3936 this.traceSheetEL?.setAttribute('mode', 'hidden'); 3937 progress && progress('rest timershaft', 8); 3938 this.timerShaftEL?.reset(); 3939 progress && progress('clear cache', 10); 3940 HeapDataInterface.getInstance().clearData(); 3941 procedurePool.clearCache(); 3942 Utils.clearData(); 3943 procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: any) => {}); 3944 procedurePool.submitWithName('logic1', 'clear', {}, undefined, (res: any) => {}); 3945 } 3946 3947 init = async (param: { buf?: ArrayBuffer; url?: string }, wasmConfigUri: string, progress: Function) => { 3948 progress('Load database', 6); 3949 this.rowsPaneEL!.scroll({ 3950 top: 0, 3951 left: 0, 3952 }); 3953 if (param.buf) { 3954 let configJson = ''; 3955 try { 3956 configJson = await fetch(wasmConfigUri).then((res) => res.text()); 3957 } catch (e) { 3958 error('getWasmConfigFailed', e); 3959 } 3960 let parseConfig = FlagsConfig.getSpTraceStreamParseConfig(); 3961 let { status, msg, sdkConfigMap } = await threadPool.initSqlite(param.buf, parseConfig, configJson, progress); 3962 if (!status) { 3963 return { status: false, msg: msg }; 3964 } 3965 SpSystemTrace.SDK_CONFIG_MAP = sdkConfigMap == undefined ? undefined : sdkConfigMap; 3966 } 3967 if (param.url) { 3968 let { status, msg } = await threadPool.initServer(param.url, progress); 3969 if (!status) { 3970 return { status: false, msg: msg }; 3971 } 3972 } 3973 await this.chartManager?.init(progress); 3974 let rowId: string = ''; 3975 this.rowsEL?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it: any) => { 3976 if (it.name.includes('Ark Ts')) { 3977 rowId = it.rowId; 3978 } 3979 it.addEventListener('expansion-change', this.extracted(it)); 3980 }); 3981 progress('completed', 100); 3982 info('All TraceRow Data initialized'); 3983 this.loadTraceCompleted = true; 3984 this.rowsEL!.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => { 3985 if (rowId !== '' && (it.rowId?.includes(rowId) || it.name.includes(rowId))) { 3986 it.addTemplateTypes('Ark Ts'); 3987 for (let child of it.childrenList) { 3988 child.addTemplateTypes('Ark Ts'); 3989 } 3990 } 3991 if (it.folder) { 3992 let offsetYTimeOut: any = undefined; 3993 it.addEventListener('expansion-change', (event: any) => { 3994 JankStruct.delJankLineFlag = false; 3995 if (offsetYTimeOut) { 3996 clearTimeout(offsetYTimeOut); 3997 } 3998 if (event.detail.expansion) { 3999 offsetYTimeOut = setTimeout(() => { 4000 this.linkNodes.forEach((linkNode) => { 4001 JankStruct.selectJankStructList?.forEach((selectStruct: any) => { 4002 if (event.detail.rowId == selectStruct.pid) { 4003 JankStruct.selectJankStruct = selectStruct; 4004 JankStruct.hoverJankStruct = selectStruct; 4005 } 4006 }); 4007 if (linkNode[0].rowEL.collect) { 4008 linkNode[0].rowEL.translateY = linkNode[0].rowEL.getBoundingClientRect().top - 195; 4009 } else { 4010 linkNode[0].rowEL.translateY = linkNode[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 4011 } 4012 linkNode[0].y = linkNode[0].rowEL!.translateY! + linkNode[0].offsetY; 4013 if (linkNode[1].rowEL.collect) { 4014 linkNode[1].rowEL.translateY = linkNode[1].rowEL.getBoundingClientRect().top - 195; 4015 } else { 4016 linkNode[1].rowEL.translateY = linkNode[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 4017 } 4018 linkNode[1].y = linkNode[1].rowEL!.translateY! + linkNode[1].offsetY; 4019 }); 4020 }, 300); 4021 } else { 4022 if (JankStruct!.selectJankStruct) { 4023 JankStruct.selectJankStructList?.push(<JankStruct>JankStruct!.selectJankStruct); 4024 } 4025 offsetYTimeOut = setTimeout(() => { 4026 this.linkNodes?.forEach((linkNode) => { 4027 if (linkNode[0].rowEL.collect) { 4028 linkNode[0].rowEL.translateY = linkNode[0].rowEL.getBoundingClientRect().top - 195; 4029 } else { 4030 linkNode[0].rowEL.translateY = linkNode[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 4031 } 4032 linkNode[0].y = linkNode[0].rowEL!.translateY! + linkNode[0].offsetY; 4033 if (linkNode[1].rowEL.collect) { 4034 linkNode[1].rowEL.translateY = linkNode[1].rowEL.getBoundingClientRect().top - 195; 4035 } else { 4036 linkNode[1].rowEL.translateY = linkNode[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop; 4037 } 4038 linkNode[1].y = linkNode[1].rowEL!.translateY! + linkNode[1].offsetY; 4039 }); 4040 }, 300); 4041 } 4042 let refreshTimeOut = setTimeout(() => { 4043 this.refreshCanvas(true); 4044 clearTimeout(refreshTimeOut); 4045 }, 360); 4046 }); 4047 } 4048 this.intersectionObserver?.observe(it); 4049 }); 4050 return { status: true, msg: 'success' }; 4051 }; 4052 4053 private extracted(it: any) { 4054 return () => { 4055 if (it.hasAttribute('expansion')) { 4056 this.shadowRoot?.querySelectorAll<any>(`[row-parent-id='${it.rowId}']`).forEach((child) => { 4057 if (child.folder) { 4058 child.addEventListener('expansion-change', this.extracted(child)); 4059 } 4060 this.intersectionObserver?.observe(child); 4061 }); 4062 } else { 4063 this.shadowRoot?.querySelectorAll<any>(`[row-parent-id='${it.rowId}']`).forEach((child) => { 4064 this.intersectionObserver?.unobserve(child); 4065 }); 4066 } 4067 this.refreshCanvas(false); 4068 }; 4069 } 4070 4071 displayTip(row: TraceRow<any>, struct: any, html: string) { 4072 let x = row.hoverX + 248; 4073 let y = row.getBoundingClientRect().top - 195 + (this.rowsPaneEL?.scrollTop ?? 0); 4074 if ((struct === undefined || struct === null) && this.tipEL) { 4075 this.tipEL.style.display = 'none'; 4076 return; 4077 } 4078 if (this.tipEL) { 4079 this.tipEL.innerHTML = html; 4080 if (row.rowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER) { 4081 this.tipEL.style.maxWidth = row.clientWidth / 3 + 'px'; 4082 this.tipEL.style.wordBreak = ' break-all'; 4083 this.tipEL.style.height = 'unset'; 4084 this.tipEL.style.display = 'block'; 4085 y = row.getBoundingClientRect().top - 195 + (this.rowsPaneEL?.scrollTop ?? 0) + struct.depth * 20; 4086 } else { 4087 this.tipEL.style.display = 'flex'; 4088 this.tipEL.style.height = row.style.height; 4089 y = row.getBoundingClientRect().top - 195 + (this.rowsPaneEL?.scrollTop ?? 0); 4090 } 4091 if (x + this.tipEL.clientWidth > (this.canvasPanel!.clientWidth ?? 0)) { 4092 this.tipEL.style.transform = `translateX(${x - this.tipEL.clientWidth - 1}px) translateY(${y}px)`; 4093 } else { 4094 this.tipEL.style.transform = `translateX(${x}px) translateY(${y}px)`; 4095 } 4096 } 4097 } 4098 4099 queryCPUWakeUpList(data: WakeupBean) { 4100 TabPaneCurrentSelection.queryCPUWakeUpListFromBean(data).then((a: any) => { 4101 if (a === null) { 4102 return null; 4103 } 4104 SpSystemTrace.wakeupList.push(a); 4105 this.queryCPUWakeUpList(a); 4106 }); 4107 } 4108 4109 wakeupListNull() { 4110 SpSystemTrace.wakeupList = []; 4111 } 4112 4113 initPointToEvent() { 4114 this.eventMap = { 4115 'cpu-data': 'Cpu', 4116 'cpu-state': 'Cpu State', 4117 'cpu-freq': 'Cpu Frequency', 4118 'cpu-limit-freq': 'Cpu Freq Limit', 4119 process: 'Process', 4120 'native-memory': 'Native Memory', 4121 thread: 'Thread', 4122 func: 'Func', 4123 mem: 'Memory', 4124 'virtual-memory-cell': 'Virtual Memory', 4125 'virtual-memory-group': 'Virtual Memory', 4126 fps: 'FPS', 4127 'ability-monitor': 'Ability Monitor', 4128 'cpu-ability': 'Cpu Ability', 4129 'memory-ability': 'Memory Ability', 4130 'disk-ability': 'DiskIO Ability', 4131 'network-ability': 'Network Ability', 4132 sdk: 'Sdk', 4133 'sdk-counter': 'SDK Counter', 4134 'sdk-slice': 'Sdk Slice', 4135 energy: 'Energy', 4136 'power-energy': 'Power Event', 4137 'system-energy': 'System Event', 4138 'anomaly-energy': 'Anomaly Event', 4139 'clock-group': 'Clocks', 4140 clock: 'clock', 4141 'irq-group': 'Irqs', 4142 irq: 'irq', 4143 hiperf: 'HiPerf (All)', 4144 'hiperf-event': 'HiPerf Event', 4145 'hiperf-report': 'HiPerf Report', 4146 'hiperf-process': 'HiPerf Process', 4147 'hiperf-thread': 'HiPerf Thread', 4148 'js-memory': 'Js Memory', 4149 }; 4150 } 4151 4152 initHtml(): string { 4153 return ` 4154 <style> 4155 :host{ 4156 display: block; 4157 width: 100%; 4158 height: 100%; 4159 } 4160 .timer-shaft{ 4161 width: 100%; 4162 z-index: 2; 4163 } 4164 .rows-pane{ 4165 overflow: overlay; 4166 overflow-anchor: none; 4167 /*height: 100%;*/ 4168 max-height: calc(100vh - 147px - 48px); 4169 } 4170 .rows{ 4171 color: #fff; 4172 display: flex; 4173 box-sizing: border-box; 4174 flex-direction: column; 4175 overflow-y: auto; 4176 flex: 1; 4177 width: 100%; 4178 background: var(--dark-background4,#ffffff); 4179 /*scroll-behavior: smooth;*/ 4180 } 4181 .favorite-rows{ 4182 width: 100%; 4183 position:fixed; 4184 overflow-y: auto; 4185 overflow-x: hidden; 4186 z-index:1001; 4187 background: var(--dark-background5,#ffffff); 4188 box-shadow: 0 10px 10px #00000044; 4189 } 4190 :host([disable]) .container{ 4191 pointer-events: none; 4192 } 4193 .container{ 4194 width: 100%; 4195 box-sizing: border-box; 4196 height: 100%; 4197 display: grid; 4198 grid-template-columns: 1fr; 4199 grid-template-rows: min-content 1fr min-content; 4200 /*grid-template-areas: 'head'*/ 4201 /*'body'*/ 4202 /*'sheet';*/ 4203 position:relative; 4204 } 4205 .panel-canvas{ 4206 position: absolute; 4207 top: 0; 4208 right: 0px; 4209 bottom: 0px; 4210 width: 100%; 4211 /*height: calc(100vh - 195px);*/ 4212 height: 100%; 4213 box-sizing: border-box; 4214 /*background: #f0f0f0;*/ 4215 /*border: 1px solid #000000;*/ 4216 z-index: 0; 4217 } 4218 .panel-canvas-favorite{ 4219 width: 100% ; 4220 display: block; 4221 position: absolute; 4222 height: 0; 4223 top: 0; 4224 right: 0; 4225 box-sizing: border-box; 4226 z-index: 100; 4227 } 4228 .trace-sheet{ 4229 cursor: default; 4230 } 4231 .tip{ 4232 z-index: 1001; 4233 position: absolute; 4234 top: 0; 4235 left: 0; 4236 /*height: 100%;*/ 4237 background-color: white; 4238 border: 1px solid #f9f9f9; 4239 width: auto; 4240 font-size: 8px; 4241 color: #50809e; 4242 flex-direction: column; 4243 justify-content: center; 4244 align-items: flex-start; 4245 padding: 2px 10px; 4246 box-sizing: border-box; 4247 display: none; 4248 user-select: none; 4249 } 4250 4251 </style> 4252 <div class="container"> 4253 <timer-shaft-element class="timer-shaft" style="position: relative;top: 0"></timer-shaft-element> 4254 <div class="rows-pane" style="position: relative;flex-direction: column;overflow-x: hidden;"> 4255 <div class="favorite-rows"> 4256 <canvas id="canvas-panel-favorite" class="panel-canvas-favorite" ondragstart="return false"></canvas> 4257 </div> 4258 <canvas id="canvas-panel" class="panel-canvas" ondragstart="return false"></canvas> 4259 <div class="spacer" ondragstart="return false"></div> 4260 <div class="rows" ondragstart="return false"></div> 4261 <div id="tip" class="tip"></div> 4262 </div> 4263 <trace-sheet class="trace-sheet" mode="hidden" ondragstart="return false"></trace-sheet> 4264 </div> 4265 `; 4266 } 4267} 4268