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 unknown KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { SpSystemTrace } from './SpSystemTrace'; 17import { TabPaneFrequencySample } from './trace/sheet/cpu/TabPaneFrequencySample'; 18import { TabPaneCounterSample } from './trace/sheet/cpu/TabPaneCounterSample'; 19import { RangeSelect } from './trace/base/RangeSelect'; 20import { TraceRow } from './trace/base/TraceRow'; 21import { SportRuler } from './trace/timer-shaft/SportRuler'; 22import { SelectionParam } from '../bean/BoxSelection'; 23import { error, info } from '../../log/Log'; 24import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; 25import { queryEbpfSamplesCount } from '../database/sql/Memory.sql'; 26import { SpChartManager } from './chart/SpChartManager'; 27import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread'; 28import { FlagsConfig } from './SpFlags'; 29import { threadPool, threadPool2 } from '../database/SqlLite'; 30import { JankStruct } from '../database/ui-worker/ProcedureWorkerJank'; 31import { CpuStruct } from '../database/ui-worker/cpu/ProcedureWorkerCPU'; 32import { PairPoint } from '../database/ui-worker/ProcedureWorkerCommon'; 33import { TraceSheet } from './trace/base/TraceSheet'; 34import { TimerShaftElement } from './trace/TimerShaftElement'; 35import { SpChartList } from './trace/SpChartList'; 36type HTMLElementAlias = HTMLElement | null | undefined; 37import { Utils } from './trace/base/Utils'; 38 39function rightButtonOnClick(sp: SpSystemTrace, rightStar: HTMLElementAlias): unknown { 40 Object.assign(sp, { 41 ext(): string { 42 return 'Handle the right button click event'; 43 }, 44 }); 45 46 return function (event: unknown): void { 47 if (SpSystemTrace.btnTimer) { 48 return; 49 } 50 // 唤醒树有值则不再重复添加 51 const startIndex = CpuStruct.selectCpuStruct!.displayProcess?.indexOf('['); 52 if (SpSystemTrace.wakeupList.length === 0) { 53 SpSystemTrace.wakeupList.unshift(CpuStruct.wakeupBean!); 54 sp.queryCPUWakeUpList(CpuStruct.wakeupBean!); 55 CpuStruct.selectCpuStruct!.ts = CpuStruct.selectCpuStruct!.startTime; 56 CpuStruct.selectCpuStruct!.thread = CpuStruct.selectCpuStruct!.name; 57 CpuStruct.selectCpuStruct!.pid = CpuStruct.selectCpuStruct!.processId; 58 CpuStruct.selectCpuStruct!.process = CpuStruct.selectCpuStruct!.displayProcess?.substring(0, startIndex).trim(); 59 CpuStruct.selectCpuStruct!.itid = CpuStruct.wakeupBean!.itid; 60 sessionStorage.setItem('saveselectcpustruct', JSON.stringify(CpuStruct.selectCpuStruct)); 61 } else { 62 sp.wakeupListNull(); 63 SpSystemTrace.wakeupList.unshift(CpuStruct.wakeupBean!); 64 sp.queryCPUWakeUpList(CpuStruct.wakeupBean!); 65 CpuStruct.selectCpuStruct!.ts = CpuStruct.selectCpuStruct!.startTime; 66 CpuStruct.selectCpuStruct!.thread = CpuStruct.selectCpuStruct!.name; 67 CpuStruct.selectCpuStruct!.pid = CpuStruct.selectCpuStruct!.processId; 68 CpuStruct.selectCpuStruct!.process = CpuStruct.selectCpuStruct!.displayProcess?.substring(0, startIndex).trim(); 69 CpuStruct.selectCpuStruct!.itid = CpuStruct.wakeupBean!.itid; 70 sessionStorage.setItem('saveselectcpustruct', JSON.stringify(CpuStruct.selectCpuStruct)); 71 } 72 setTimeout(() => { 73 requestAnimationFrame(() => sp.refreshCanvas(false)); 74 }, 300); 75 rightStar!.style.visibility = 'visible'; 76 rightStar!.style.cursor = 'pointer'; 77 SpSystemTrace.btnTimer = setTimeout((): void => { 78 SpSystemTrace.btnTimer = null; // 2.清空节流阀,方便下次开启定时器 79 }, 2000); 80 }; 81} 82function rightStarOnClick(sp: SpSystemTrace) { 83 return function (ev: unknown): void { 84 let wakeupLists = []; 85 wakeupLists.push(CpuStruct.selectCpuStruct?.cpu); 86 for (let wakeupBean of SpSystemTrace.wakeupList) { 87 wakeupLists.push(wakeupBean.cpu); 88 } 89 let wakeupCpuLists = Array.from(new Set(wakeupLists)).sort(); 90 for (let wakeupCpu of wakeupCpuLists) { 91 // @ts-ignore 92 let cpuFavoriteRow: unknown = sp.shadowRoot?.querySelector<TraceRow<unknown>>( 93 `trace-row[row-type='cpu-data'][row-id='${Utils.getDistributedRowId(wakeupCpu)}']` 94 ); 95 if (cpuFavoriteRow === null || cpuFavoriteRow === undefined) { 96 continue; 97 } 98 // @ts-ignore 99 cpuFavoriteRow!.setAttribute('collect-type', ''); 100 let replaceRow = document.createElement('div'); 101 // @ts-ignore 102 replaceRow.setAttribute('row-id', `${cpuFavoriteRow.rowId}-${cpuFavoriteRow.rowType}`); 103 replaceRow.setAttribute('type', 'replaceRow'); 104 // @ts-ignore 105 replaceRow.setAttribute('row-parent-id', cpuFavoriteRow.rowParentId); 106 replaceRow.style.display = 'none'; 107 // @ts-ignore 108 cpuFavoriteRow.rowHidden = !cpuFavoriteRow.hasAttribute('scene'); 109 // @ts-ignore 110 if (sp.rowsEL!.contains(cpuFavoriteRow)) { 111 // @ts-ignore 112 sp.rowsEL!.replaceChild(replaceRow, cpuFavoriteRow); 113 } 114 // @ts-ignore 115 cpuFavoriteRow.tampName = cpuFavoriteRow.name; 116 // @ts-ignore 117 sp.favoriteChartListEL!.insertRow(cpuFavoriteRow, cpuFavoriteRow.traceId || sp.currentCollectGroup, true); 118 // @ts-ignore 119 sp.collectRows.push(cpuFavoriteRow); 120 sp.timerShaftEL?.displayCollect(sp.collectRows.length !== 0); 121 sp.currentClickRow = null; 122 // @ts-ignore 123 cpuFavoriteRow.setAttribute('draggable', 'true'); 124 // @ts-ignore 125 cpuFavoriteRow.addEventListener('dragstart', cpuFavoriteRowDragStart(sp, cpuFavoriteRow)); 126 // @ts-ignore 127 cpuFavoriteRow.addEventListener('dragover', cpuFavoriteRowDragOver(sp)); 128 // @ts-ignore 129 cpuFavoriteRow.addEventListener('drop', cpuFavoriteRowDropHandler(sp, cpuFavoriteRow)); 130 // @ts-ignore 131 cpuFavoriteRow.addEventListener('dragend', cpuFavoriteRowDragendHandler(sp)); 132 } 133 sp.refreshFavoriteCanvas(); 134 sp.refreshCanvas(true); 135 }; 136} 137function cpuFavoriteRowDragStart(sp: SpSystemTrace, cpuFavoriteRow: unknown) { 138 return function (): void { 139 // @ts-ignore 140 sp.currentClickRow = cpuFavoriteRow; 141 }; 142} 143function cpuFavoriteRowDragOver(sp: SpSystemTrace) { 144 return function (ev: unknown): void { 145 // @ts-ignore 146 ev.preventDefault(); 147 // @ts-ignore 148 ev.dataTransfer.dropEffect = 'move'; 149 }; 150} 151function cpuFavoriteRowDropHandler(sp: SpSystemTrace, cpuFavoriteRow: unknown) { 152 return function (ev: unknown): void { 153 if (sp.favoriteChartListEL && sp.currentClickRow && sp.currentClickRow !== cpuFavoriteRow) { 154 // @ts-ignore 155 let rect = cpuFavoriteRow.getBoundingClientRect(); 156 // @ts-ignore 157 if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) { 158 //向上移动 159 // @ts-ignore 160 sp.favoriteChartListEL.insertRowBefore(sp.currentClickRow, cpuFavoriteRow); 161 // @ts-ignore 162 } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) { 163 //向下移动 164 // @ts-ignore 165 sp.favoriteChartListEL.insertRowBefore(sp.currentClickRow, cpuFavoriteRow.nextSibling); 166 } 167 sp.refreshFavoriteCanvas(); 168 } 169 }; 170} 171function cpuFavoriteRowDragendHandler(sp: SpSystemTrace): () => void { 172 return function (): void { 173 sp.linkNodes.forEach((itln) => { 174 if (itln[0].rowEL.collect) { 175 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 176 } else { 177 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 178 } 179 if (itln[1].rowEL.collect) { 180 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 181 } else { 182 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 183 } 184 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 185 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 186 }); 187 sp.currentClickRow = null; 188 }; 189} 190function triangleFlagHandler(sp: SpSystemTrace): (event: unknown) => void { 191 return function (event: unknown): void { 192 //@ts-ignore 193 let temporaryTime = sp.timerShaftEL?.drawTriangle(event.detail.time, event.detail.type); 194 //@ts-ignore 195 if (event.detail.timeCallback && temporaryTime) { 196 //@ts-ignore 197 event.detail.timeCallback(temporaryTime); 198 } 199 }; 200} 201function numberCalibrationHandler(sp: SpSystemTrace): (event: unknown) => void { 202 return function (event: unknown): void { 203 // @ts-ignore 204 sp.timerShaftEL!.sportRuler!.times = event.detail.time; 205 // @ts-ignore 206 sp.timerShaftEL!.sportRuler!.counts = event.detail.counts; 207 // @ts-ignore 208 sp.timerShaftEL!.sportRuler!.durations = event.detail.durations; 209 sp.timerShaftEL!.sportRuler?.draw(); 210 }; 211} 212function flagChangeHandler(sp: SpSystemTrace): (event: unknown) => void { 213 return function (event: unknown): void { 214 // @ts-ignore 215 sp.timerShaftEL?.modifyFlagList(event.detail); 216 // @ts-ignore 217 if (event.detail.hidden) { 218 //@ts-ignore 219 sp.selectFlag = undefined; 220 if (sp._flagList.length <= 0) { 221 let showTab = sp.getShowTab(); 222 showTab = showTab.filter((it) => it !== 'box-flag'); 223 if (TraceRow.rangeSelectObject && showTab.length > 0) { 224 sp.traceSheetEL?.displayTab(...showTab); 225 } else { 226 sp.traceSheetEL?.setMode('hidden'); 227 } 228 } 229 sp.refreshCanvas(true); 230 } 231 }; 232} 233function slicesChangeHandler(sp: SpSystemTrace): (event: unknown) => void { 234 return function (event: unknown): void { 235 // @ts-ignore 236 sp.timerShaftEL?.modifySlicesList(event.detail); 237 // @ts-ignore 238 if (event.detail.hidden) { 239 sp.slicestime = null; 240 if (sp._slicesList.length <= 0) { 241 let showTab = sp.getShowTab(); 242 showTab = showTab.filter((it) => it !== 'tabpane-current'); 243 if (TraceRow.rangeSelectObject && showTab.length > 0) { 244 sp.traceSheetEL?.displayTab(...showTab); 245 } else { 246 sp.traceSheetEL?.setMode('hidden'); 247 } 248 } 249 sp.refreshCanvas(true); 250 } 251 }; 252} 253function collectHandler(sp: SpSystemTrace): (event: unknown) => void { 254 return function (event: unknown): void { 255 // @ts-ignore 256 let currentRow = event.detail.row; 257 if (currentRow.collect) { 258 collectHandlerYes(sp, currentRow, event); 259 } else { 260 collectHandlerNo(sp, currentRow, event); 261 } 262 sp.timerShaftEL?.displayCollect(sp.collectRows.length !== 0); 263 sp.refreshFavoriteCanvas(); 264 sp.refreshCanvas(true); 265 sp.linkNodes.forEach((itln) => { 266 if (itln[0].rowEL === currentRow) { 267 if (itln[0].rowEL.collect) { 268 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 269 } else { 270 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 271 } 272 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 273 } else if (itln[1].rowEL === currentRow) { 274 if (itln[1].rowEL.collect) { 275 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 276 } else { 277 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 278 } 279 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 280 } 281 }); 282 // 收藏夹元素拖动排序功能 283 sp.currentClickRow = null; 284 currentRow.setAttribute('draggable', 'true'); 285 currentRow.addEventListener('dragstart', () => { 286 sp.currentClickRow = currentRow; 287 }); 288 currentRow.addEventListener('dragover', (ev: unknown) => { 289 // @ts-ignore 290 ev.preventDefault(); 291 // @ts-ignore 292 ev.dataTransfer.dropEffect = 'move'; 293 }); 294 currentRow.addEventListener('drop', collectHandlerDrop(sp, currentRow)); 295 currentRow.addEventListener('dragend', collectHandlerDragEnd(sp)); 296 }; 297} 298function collectHandlerNo(sp: SpSystemTrace, currentRow: unknown, event: unknown): void { 299 // @ts-ignore 300 sp.favoriteChartListEL?.deleteRow(currentRow, event.detail.type !== 'auto-collect'); 301 // @ts-ignore 302 if (event.detail.type !== 'auto-collect') { 303 // @ts-ignore 304 let rowIndex = sp.collectRows.indexOf(currentRow); 305 if (rowIndex !== -1) { 306 sp.collectRows.splice(rowIndex, 1); 307 } 308 } 309 let row = currentRow; 310 let allowExpansionRow = []; 311 // @ts-ignore 312 while (row.hasParentRowEl) { 313 // @ts-ignore 314 let parent = row.parentRowEl; 315 allowExpansionRow.push(parent); 316 row = parent; 317 } 318 if (allowExpansionRow.length === 1) { 319 for (let index: number = allowExpansionRow.length - 1; index >= 0; index--) { 320 if (allowExpansionRow[index]?.hasAttribute('scene')) { 321 if (allowExpansionRow[index]!.expansion) { 322 allowExpansionRow[index].updateChildRowStatus(); 323 } else { 324 allowExpansionRow[index].expansion = true; 325 } 326 } 327 } 328 } else { 329 for (let index: number = allowExpansionRow.length - 1; index >= 0; index--) { 330 let currentItemRow = allowExpansionRow[index]; 331 if (currentItemRow.hasAttribute('scene')) { 332 if (currentItemRow.rowParentId !== '') { 333 if (currentItemRow.expansion) { 334 currentItemRow.updateChildRowStatus(); 335 } else { 336 currentItemRow.expansion = true; 337 } 338 } 339 else { 340 currentItemRow.expansion = true; 341 let number = currentItemRow.childrenList.indexOf(currentRow); 342 if (number !== -1) {// 确保 currentRow 在 childrenList 中 343 let childrenEl = currentItemRow.childrenList[number]; 344 let childrenNextEl = currentItemRow.childrenList[number + 1]; 345 if (childrenEl) { 346 if (childrenNextEl) { 347 currentItemRow.parentNode.insertBefore(childrenEl, currentItemRow.childrenList[number + 1]); 348 } else if (childrenEl.nextSibling) { 349 currentItemRow.parentNode.insertBefore(childrenEl, childrenEl.nextSibling); 350 } else { 351 currentItemRow.parentNode.appendChild(childrenEl); 352 } 353 } 354 } 355 } 356 } 357 } 358 } 359 allowExpansionRow.length = 0; 360 // @ts-ignore 361 let traceId = currentRow.traceId ? `${currentRow.traceId}-` : ''; 362 let replaceRow = sp.rowsEL!.querySelector<HTMLCanvasElement>( 363 // @ts-ignore 364 `div[row-id='${traceId}${currentRow.rowId}-${currentRow.rowType}']` 365 ); 366 // 取消收藏时,删除父亲ID 367 // @ts-ignore 368 currentRow.name = currentRow.tampName; 369 if (replaceRow !== null) { 370 // @ts-ignore 371 sp.rowsEL!.replaceChild(currentRow, replaceRow); 372 // @ts-ignore 373 currentRow.style.boxShadow = '0 10px 10px #00000000'; 374 } 375} 376function collectHandlerYes(sp: SpSystemTrace, currentRow: unknown, event: unknown): void { 377 if (!sp.collectRows.find((find) => find === currentRow)) { 378 // @ts-ignore 379 sp.collectRows.push(currentRow); 380 } 381 let replaceRow = document.createElement('div'); 382 // @ts-ignore 383 let traceId = currentRow.traceId ? `${currentRow.traceId}-` : ''; 384 // @ts-ignore 385 replaceRow.setAttribute('row-id', `${traceId}${currentRow.rowId}-${currentRow.rowType}`); 386 replaceRow.setAttribute('type', 'replaceRow'); 387 // @ts-ignore 388 replaceRow.setAttribute('row-parent-id', currentRow.rowParentId); 389 replaceRow.style.display = 'none'; 390 // @ts-ignore 391 if (!currentRow.hasAttribute('scene')) { 392 // @ts-ignore 393 currentRow.setAttribute('row-hidden', ''); 394 } else { 395 // @ts-ignore 396 currentRow.removeAttribute('row-hidden'); 397 } 398 // 添加收藏时,在线程名前面追加父亲ID 399 // @ts-ignore 400 let rowParentId = currentRow.rowParentId; 401 // @ts-ignore 402 currentRow.tampName = currentRow.name; 403 if (rowParentId) { 404 // @ts-ignore 405 let parentRows = sp.shadowRoot?.querySelectorAll<TraceRow<unknown>>(`trace-row[row-id='${rowParentId}']`); 406 parentRows?.forEach((parentRow) => { 407 if ( 408 parentRow?.name && 409 // @ts-ignore 410 parentRow?.name !== currentRow.name && 411 !parentRow.rowType!.startsWith('cpu') && 412 !parentRow.rowType!.startsWith('thread') && 413 !parentRow.rowType!.startsWith('func') && 414 // @ts-ignore 415 !currentRow.name.includes(parentRow.name) 416 ) { 417 // @ts-ignore 418 currentRow.name += `(${parentRow.name})`; 419 } 420 }); 421 } 422 // @ts-ignore 423 if (!currentRow.hasParentRowEl) { 424 // @ts-ignore 425 sp.rowsEL!.replaceChild(replaceRow, currentRow); 426 } 427 // @ts-ignore 428 let group = currentRow.traceId || sp.currentCollectGroup; 429 // @ts-ignore 430 sp.favoriteChartListEL?.insertRow(currentRow, group, event.detail.type !== 'auto-collect'); 431} 432function collectHandlerDrop(sp: SpSystemTrace, currentRow: HTMLDivElement | undefined | null): (ev: unknown) => void { 433 return function (ev: unknown) { 434 if (sp.favoriteChartListEL !== null && sp.currentClickRow !== null && sp.currentClickRow !== currentRow) { 435 // @ts-ignore 436 let rect = currentRow!.getBoundingClientRect(); 437 // @ts-ignore 438 if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) { 439 //向上移动 440 sp.favoriteChartListEL!.insertRowBefore(sp.currentClickRow!, currentRow!); 441 // @ts-ignore 442 } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) { 443 //向下移动 444 sp.favoriteChartListEL!.insertRowBefore(sp.currentClickRow!, currentRow!.nextSibling!); 445 } 446 sp.refreshFavoriteCanvas(); 447 } 448 }; 449} 450function collectHandlerDragEnd(sp: SpSystemTrace): (ev: unknown) => void { 451 return function (ev: unknown): void { 452 sp.linkNodes.forEach((itln) => { 453 if (itln[0].rowEL.collect) { 454 if (sp.timerShaftEL?._checkExpand) { 455 itln[0].rowEL.translateY = 456 itln[0].rowEL.getBoundingClientRect().top - 195 + sp.timerShaftEL._usageFoldHeight!; 457 } else { 458 itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195; 459 } 460 } else { 461 itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 462 } 463 if (itln[1].rowEL.collect) { 464 if (sp.timerShaftEL?._checkExpand) { 465 itln[1].rowEL.translateY = 466 itln[1].rowEL.getBoundingClientRect().top - 195 + sp.timerShaftEL._usageFoldHeight!; 467 } else { 468 itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195; 469 } 470 } else { 471 itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 472 } 473 itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY; 474 itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY; 475 }); 476 sp.currentClickRow = null; 477 }; 478} 479function selectHandler(sp: SpSystemTrace): void { 480 sp.rangeSelect.selectHandler = (rows, refreshCheckBox): void => { 481 rows.forEach((item) => { 482 sp.setAttribute('clickRow', item.rowType!); 483 sp.setAttribute('rowName', item.name); 484 sp.setAttribute('rowId', item.rowId!); 485 }); 486 if (rows.length === 0) { 487 const allRows = [ 488 // @ts-ignore 489 ...sp.shadowRoot!.querySelectorAll<TraceRow<unknown>>('trace-row'), 490 ...sp.favoriteChartListEL!.getAllCollectRows(), 491 ]; 492 for (const row of allRows) { 493 row.checkType = '-1'; 494 if (row.folder) { 495 row.childrenList.forEach((item) => { 496 row.checkType = '-1'; 497 }); 498 } 499 } 500 sp.refreshCanvas(true); 501 if (!SportRuler.isMouseInSportRuler) { 502 sp.traceSheetEL?.setMode('hidden'); 503 } 504 return; 505 } 506 let checkRows = rows; 507 if (!refreshCheckBox) { 508 checkRows = [ 509 // @ts-ignore 510 ...sp.shadowRoot!.querySelectorAll<TraceRow<unknown>>(`trace-row[check-type='2']`), 511 ...sp.favoriteChartListEL!.getAllSelectCollectRows(), 512 ]; 513 } 514 selectHandlerRefreshCheckBox(sp, checkRows, refreshCheckBox); 515 if (!sp.isSelectClick) { 516 sp.rangeTraceRow = []; 517 } 518 selectHandlerRows(sp, checkRows); 519 }; 520} 521// @ts-ignore 522function selectHandlerRefreshCheckBox(sp: SpSystemTrace, rows: Array<TraceRow<unknown>>, refreshCheckBox: boolean): void { 523 if (refreshCheckBox) { 524 if (rows.length > 0) { 525 sp.queryAllTraceRow().forEach((row) => (row.checkType = '0')); 526 rows.forEach((it) => (it.checkType = '2')); 527 } else { 528 sp.queryAllTraceRow().forEach((row) => (row.checkType = '-1')); 529 return; 530 } 531 } 532} 533// @ts-ignore 534function selectHandlerRows(sp: SpSystemTrace, rows: Array<TraceRow<unknown>>): void { 535 let selection = new SelectionParam(); 536 selection.traceId = Utils.currentSelectTrace; 537 selection.cpuStateRowsId = sp.stateRowsId; 538 selection.leftNs = TraceRow.rangeSelectObject?.startNS || 0; 539 selection.rightNs = TraceRow.rangeSelectObject?.endNS || 0; 540 selection.recordStartNs = Utils.getInstance().getRecordStartNS(Utils.currentSelectTrace); 541 rows.forEach((it) => { 542 selection.pushSelection(it, sp); 543 if (sp.rangeTraceRow!.length !== rows.length) { 544 let event = sp.createPointEvent(it); 545 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 546 action: 'trace_row', // @ts-ignore 547 event: event, 548 }); 549 } 550 }); 551 if (selection.diskIOipids.length > 0 && !selection.diskIOLatency) { 552 selection.promiseList.push( 553 queryEbpfSamplesCount( 554 TraceRow.rangeSelectObject?.startNS || 0, 555 TraceRow.rangeSelectObject?.endNS || 0, 556 selection.diskIOipids 557 ).then((res) => { 558 if (res.length > 0) { 559 //@ts-ignore 560 selection.fsCount = res[0].fsCount; 561 //@ts-ignore 562 selection.vmCount = res[0].vmCount; 563 } 564 return new Promise((resolve) => resolve(1)); 565 }) 566 ); 567 } 568 sp.rangeTraceRow = rows; 569 sp.isSelectClick = false; 570 sp.selectStructNull(); 571 sp.timerShaftEL?.removeTriangle('inverted'); 572 if (selection.promiseList.length > 0) { 573 Promise.all(selection.promiseList).then(() => { 574 selection.promiseList = []; 575 sp.traceSheetEL?.rangeSelect(selection); 576 }); 577 } else { 578 sp.traceSheetEL?.rangeSelect(selection); 579 } 580 sp.timerShaftEL!.selectionList.push(selection); // 保持选中对象,为后面的再次选中该框选区域做准备。 581 sp.selectionParam = selection; 582} 583function resizeObserverHandler(sp: SpSystemTrace): void { 584 // @ts-ignore 585 new ResizeObserver((entries) => { 586 TraceRow.FRAME_WIDTH = sp.clientWidth - 249 - sp.getScrollWidth(); 587 requestAnimationFrame(() => { 588 sp.timerShaftEL?.updateWidth(sp.clientWidth - 1 - sp.getScrollWidth()); 589 // @ts-ignore 590 sp.shadowRoot!.querySelectorAll<TraceRow<unknown>>('trace-row').forEach((it) => { 591 it.updateWidth(sp.clientWidth); 592 }); 593 }); 594 }).observe(sp); 595 596 new ResizeObserver((entries) => { 597 sp.canvasPanelConfig(); 598 if (sp.traceSheetEL!.getAttribute('mode') === 'hidden') { 599 sp.timerShaftEL?.removeTriangle('triangle'); 600 } 601 if (sp.favoriteChartListEL?.style.display === 'flex') { 602 sp.refreshFavoriteCanvas(); 603 } 604 sp.refreshCanvas(true); 605 }).observe(sp.rowsPaneEL!); 606} 607function mutationObserverHandler(sp: SpSystemTrace): void { 608 new MutationObserver((mutations, observer) => { 609 for (const mutation of mutations) { 610 if (mutation.type === 'attributes') { 611 if (sp.style.visibility === 'visible') { 612 if (TraceRow.rangeSelectObject && SpSystemTrace.sliceRangeMark) { 613 sp.timerShaftEL?.setSlicesMark( 614 TraceRow.rangeSelectObject.startNS || 0, 615 TraceRow.rangeSelectObject.endNS || 0, 616 false 617 ); 618 SpSystemTrace.sliceRangeMark = undefined; 619 window.publish(window.SmartEvent.UI.RefreshCanvas, {}); 620 } 621 } 622 } 623 } 624 }).observe(sp, { 625 attributes: true, 626 childList: false, 627 subtree: false, 628 }); 629} 630function intersectionObserverHandler(sp: SpSystemTrace): void { 631 sp.intersectionObserver = new IntersectionObserver( 632 (entries) => { 633 entries.forEach((it) => { 634 // @ts-ignore 635 let tr = it.target as TraceRow<unknown>; 636 // 目标元素的可见比例 637 tr.intersectionRatio = it.intersectionRatio; 638 // 判断目标元素是否可见 isIntersecting为true是可见 639 if (!it.isIntersecting) { 640 tr.sleeping = true; 641 sp.invisibleRows.indexOf(tr) === -1 && sp.invisibleRows.push(tr); 642 } else { 643 tr.sleeping = false; 644 sp.visibleRows.indexOf(tr) === -1 && sp.visibleRows.push(tr); 645 } 646 }); 647 //更新可见泳道及不可见泳道值 648 sp.visibleRows = sp.visibleRows.filter((it) => !it.sleeping); 649 sp.invisibleRows = sp.invisibleRows.filter((it) => it.sleeping); 650 if (sp.handler === -1) { 651 cancelAnimationFrame(sp.handler); 652 } 653 sp.handler = requestAnimationFrame(() => sp.refreshCanvas(false)); 654 }, 655 { threshold: [0, 0.01, 0.99, 1] } 656 ); 657} 658function observerHandler(sp: SpSystemTrace): void { 659 resizeObserverHandler(sp); 660 mutationObserverHandler(sp); 661 intersectionObserverHandler(sp); 662} 663function windowKeyDownHandler(sp: SpSystemTrace): (ev: KeyboardEvent) => void { 664 return function (ev: KeyboardEvent) { 665 if (ev.key.toLocaleLowerCase() === 'escape') { 666 sp.queryAllTraceRow().forEach((it) => { 667 it.checkType = '-1'; 668 }); 669 TraceRow.rangeSelectObject = undefined; 670 sp.rangeSelect.rangeTraceRow = []; 671 sp.selectStructNull(); 672 sp.timerShaftEL?.setSlicesMark(); 673 sp.traceSheetEL?.setMode('hidden'); 674 sp.removeLinkLinesByBusinessType('janks', 'task'); 675 } 676 }; 677} 678function smartEventSubscribe(sp: SpSystemTrace): void { 679 window.subscribe(window.SmartEvent.UI.SliceMark, (data) => sp.sliceMarkEventHandler(data)); 680 window.subscribe(window.SmartEvent.UI.TraceRowComplete, (tr) => { }); 681 window.subscribe(window.SmartEvent.UI.RefreshCanvas, () => sp.refreshCanvas(false)); 682 window.subscribe(window.SmartEvent.UI.KeyboardEnable, (tr) => { 683 //@ts-ignore 684 sp.keyboardEnable = tr.enable; 685 if (!sp.keyboardEnable) { 686 sp.stopWASD(); 687 } 688 }); //@ts-ignore 689 window.subscribe(window.SmartEvent.UI.CollapseAllLane, (collapse: boolean) => { 690 if (!collapse) { 691 // 一键折叠之前,记录当前打开的泳道图 692 // @ts-ignore 693 sp.expandRowList = Array.from(sp.rowsEL!.querySelectorAll<TraceRow<unknown>>('trace-row[folder][expansion]')) || []; 694 } 695 sp.collapseAll = true; 696 sp.setAttribute('disable', ''); 697 sp.expandRowList!.forEach((it) => (it.expansion = collapse)); 698 sp.collapseAll = false; 699 sp.removeAttribute('disable'); 700 sp.refreshCanvas(true); 701 }); 702 window.subscribe(window.SmartEvent.UI.MouseEventEnable, (tr) => { 703 //@ts-ignore 704 sp.mouseEventEnable = tr.mouseEnable; 705 if (sp.mouseEventEnable) { 706 sp.removeAttribute('disable'); 707 } else { 708 sp.setAttribute('disable', ''); 709 } 710 }); //@ts-ignore 711 window.subscribe(window.SmartEvent.UI.CollectGroupChange, (group: string) => (sp.currentCollectGroup = group)); 712} 713 714export function documentInitEvent(sp: SpSystemTrace): void { 715 if (!document) { 716 return; 717 } 718 document.addEventListener('triangle-flag', triangleFlagHandler(sp)); 719 document.addEventListener('number_calibration', numberCalibrationHandler(sp)); 720 document.addEventListener('flag-change', flagChangeHandler(sp)); 721 document.addEventListener('remarksFocus-change', remarksFocuseChangeHandler(sp)); 722 document.addEventListener('slices-change', slicesChangeHandler(sp)); 723 if (sp.timerShaftEL?.collecBtn) { 724 sp.timerShaftEL.collecBtn.onclick = (): void => { 725 if (sp.timerShaftEL!.collecBtn!.hasAttribute('close')) { 726 sp.timerShaftEL!.collecBtn!.removeAttribute('close'); 727 sp.favoriteChartListEL?.showCollectArea(); 728 } else { 729 sp.timerShaftEL!.collecBtn!.setAttribute('close', ''); 730 sp.favoriteChartListEL?.hideCollectArea(); 731 } 732 }; 733 } 734 document.addEventListener('collect', collectHandler(sp)); 735} 736 737function remarksFocuseChangeHandler(sp: SpSystemTrace): (event: unknown) => void { 738 return function (event: unknown): void { 739 // @ts-ignore 740 sp.focusTarget = event.detail; 741 }; 742} 743 744export function spSystemTraceInitElement(sp: SpSystemTrace): void { 745 window.subscribe(window.SmartEvent.UI.LoadFinishFrame, () => sp.drawAllLines()); 746 sp.traceSheetEL = sp.shadowRoot?.querySelector<TraceSheet>('.trace-sheet'); 747 if (!sp || !sp.shadowRoot || !sp.traceSheetEL) { 748 return; 749 } 750 let rightButton: HTMLElement | null | undefined = sp.traceSheetEL.shadowRoot 751 ?.querySelector('#current-selection > tabpane-current-selection') 752 ?.shadowRoot?.querySelector('#rightButton'); 753 let rightStar: HTMLElement | null | undefined = sp.traceSheetEL.shadowRoot 754 ?.querySelector('#current-selection > tabpane-current-selection') 755 ?.shadowRoot?.querySelector('#right-star'); 756 sp.tipEL = sp.shadowRoot.querySelector<HTMLDivElement>('.tip'); 757 sp.rowsPaneEL = sp.shadowRoot.querySelector<HTMLDivElement>('.rows-pane'); 758 sp.rowsEL = sp.rowsPaneEL; 759 sp.spacerEL = sp.shadowRoot.querySelector<HTMLDivElement>('.spacer'); 760 sp.timerShaftEL = sp.shadowRoot.querySelector<TimerShaftElement>('.timer-shaft'); 761 sp.favoriteChartListEL = sp.shadowRoot.querySelector<SpChartList>('#favorite-chart-list'); 762 if (!sp.traceSheetEL.shadowRoot) { 763 return; 764 } 765 sp.tabCpuFreq = sp.traceSheetEL.shadowRoot.querySelector<TabPaneFrequencySample>('tabpane-frequency-sample'); 766 sp.tabCpuState = sp.traceSheetEL.shadowRoot.querySelector<TabPaneCounterSample>('tabpane-counter-sample'); 767 sp.rangeSelect = new RangeSelect(sp); 768 // @ts-ignore 769 rightButton?.addEventListener('click', rightButtonOnClick(sp, rightStar)); 770 rightStar?.addEventListener('click', rightStarOnClick(sp)); 771 documentInitEvent(sp); 772 SpSystemTrace.scrollViewWidth = sp.getScrollWidth(); 773 selectHandler(sp); 774 observerHandler(sp); 775 window.addEventListener('keydown', windowKeyDownHandler(sp)); 776 sp.chartManager = new SpChartManager(sp); 777 sp.canvasPanel = sp.shadowRoot.querySelector<HTMLCanvasElement>('#canvas-panel')!; 778 sp.canvasPanelCtx = sp.canvasPanel.getContext('2d'); 779 sp.canvasFavoritePanelCtx = sp.favoriteChartListEL!.context(); 780 sp.canvasPanelConfig(); 781 smartEventSubscribe(sp); 782} 783 784function moveRangeToCenterAndHighlight(sp: SpSystemTrace, findEntry: unknown, currentEntry: unknown): void { 785 if (findEntry) { 786 //findEntry不在range范围内,会把它移动到泳道最左侧 787 // @ts-ignore 788 if (findEntry.startTime > TraceRow.range!.endNS || findEntry.startTime + findEntry.dur < TraceRow.range!.startNS) { 789 // @ts-ignore 790 sp.moveRangeToLeft(findEntry.startTime!, findEntry.dur!); 791 } 792 cancelCurrentTraceRowHighlight(sp, currentEntry); 793 // @ts-ignore 794 if (findEntry.type === 'cpu') { 795 findEntryTypeCpu(sp, findEntry); 796 // @ts-ignore 797 } else if (findEntry.type === 'func') { 798 findEntryTypeFunc(sp, findEntry); 799 // @ts-ignore 800 } else if (findEntry.type === 'thread||process') { 801 findEntryTypeThreadProcess(sp, findEntry); 802 // @ts-ignore 803 } else if (findEntry.type === 'sdk') { 804 findEntryTypeSdk(sp, findEntry); 805 } 806 } 807} 808 809export function cancelCurrentTraceRowHighlight(sp: SpSystemTrace, currentEntry: unknown): void { 810 // @ts-ignore 811 if (currentEntry?.type === 'cpu') { 812 // @ts-ignore 813 sp.queryAllTraceRow(`trace-row[row-type='cpu-data'][row-id='${currentEntry.cpu}']`, 814 // @ts-ignore 815 (row) => row.rowType === 'cpu-data' && row.rowId === `${currentEntry.cpu}`)[0].highlight = false; 816 // @ts-ignore 817 } else if (currentEntry?.type === 'func') { 818 // @ts-ignore 819 let funId = (currentEntry.rowId === null || currentEntry.rowId === undefined) ? `${currentEntry.funName}-${currentEntry.pid}` : currentEntry.rowId; 820 // @ts-ignore 821 let funcRowID = (currentEntry.cookie === null || currentEntry.cookie === undefined) ? `${Utils.getDistributedRowId(currentEntry.tid)}` : funId; 822 // @ts-ignore 823 let parentRow = sp.queryAllTraceRow(`trace-row[row-id='${Utils.getDistributedRowId(currentEntry.pid)}'][folder]`, 824 // @ts-ignore 825 (row) => row.rowId === `trace-row[row-id='${Utils.getDistributedRowId(currentEntry.pid)}'][folder]`)[0]; 826 if (!parentRow) { 827 return; 828 } 829 let filterRow = parentRow.childrenList.filter((child) => child.rowId === funcRowID && child.rowType === 'func')[0]; 830 filterRow.highlight = false; 831 // @ts-ignore 832 } else if (currentEntry?.type === 'sdk') { 833 // @ts-ignore 834 let parentRow = sp.shadowRoot!.querySelector<TraceRow<unknown>>("trace-row[row-type='sdk'][folder]"); 835 if (parentRow) { 836 let sdkRow = parentRow.childrenList.filter( 837 // @ts-ignore 838 (child) => child.rowId === currentEntry.rowId && child.rowType === currentEntry.rowType 839 )[0]; 840 sdkRow!.highlight = false; 841 } 842 } 843} 844 845export function spSystemTraceShowStruct( 846 sp: SpSystemTrace, 847 previous: boolean, 848 currentIndex: number, 849 structs: Array<unknown>, 850 retargetIndex?: number 851): number { 852 if (structs.length === 0) { 853 return 0; 854 } 855 let findIndex = spSystemTraceShowStructFindIndex(previous, currentIndex, structs, retargetIndex); 856 let findEntry: unknown; 857 findEntry = structs[findIndex]; 858 let currentEntry: unknown = undefined; 859 if (currentIndex >= 0) { 860 currentEntry = structs[currentIndex]; 861 } 862 moveRangeToCenterAndHighlight(sp, findEntry, currentEntry); 863 return findIndex; 864} 865 866function spSystemTraceShowStructFindIndex( 867 previous: boolean, 868 currentIndex: number, 869 structs: Array<unknown>, 870 retargetIndex: number | undefined 871): number { 872 const rangeStart = TraceRow.range!.startNS; 873 const rangeEnd = TraceRow.range!.endNS; 874 let findIndex = -1; 875 if (retargetIndex) { 876 findIndex = retargetIndex - 1; 877 } else if (previous) { 878 for (let i = structs.length - 1; i >= 0; i--) { 879 let it = structs[i]; 880 // @ts-ignore 881 if ((i < currentIndex && it.startTime! >= rangeStart && it.startTime! + it.dur! <= rangeEnd) || 882 // @ts-ignore 883 (it.startTime! + it.dur! < rangeStart)) { 884 findIndex = i; 885 break; 886 } 887 } 888 if (findIndex === -1) { 889 findIndex = structs.length - 1; 890 } 891 } else { 892 if (currentIndex > 0) { 893 if (rangeStart > SpSystemTrace.currentStartTime) { 894 SpSystemTrace.currentStartTime = rangeStart; 895 } 896 //右移rangeStart变小重新赋值 897 if (SpSystemTrace.currentStartTime > rangeStart) { 898 SpSystemTrace.currentStartTime = rangeStart;//currentIndex不在可视区时,currentIndex = -1 899 if ( 900 // @ts-ignore 901 structs[currentIndex].startTime < rangeStart || 902 // @ts-ignore 903 structs[currentIndex].startTime! + structs[currentIndex].dur! > rangeEnd 904 ) { 905 currentIndex = -1; 906 } 907 } 908 } 909 //在数组中查找比currentIndex大且在range范围内的第一个下标,如果range范围内没有返回-1 910 findIndex = structs.findIndex((it, idx) => { 911 // @ts-ignore 912 return ((idx > currentIndex && it.startTime! >= rangeStart && it.startTime! + it.dur! <= rangeEnd) || 913 // @ts-ignore 914 (it.startTime! > rangeEnd)); 915 }); 916 if (findIndex === -1) { 917 findIndex = 0; 918 } 919 } 920 return findIndex; 921} 922function findEntryTypeCpu(sp: SpSystemTrace, findEntry: unknown): void { 923 // @ts-ignore 924 CpuStruct.selectCpuStruct = findEntry; 925 CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct; 926 sp.queryAllTraceRow(`trace-row[row-type='cpu-data']`, (row): boolean => row.rowType === 'cpu-data').forEach( 927 (item): void => { 928 // @ts-ignore 929 if (item.rowId === `${Utils.getDistributedRowId(findEntry.cpu)}`) { 930 sp.rechargeCpuData( 931 // @ts-ignore 932 findEntry, // @ts-ignore 933 item.dataListCache.find((it) => it.startTime > findEntry.startTime) 934 ); 935 let _findEntry = JSON.parse(JSON.stringify(findEntry)); 936 _findEntry.type = 'thread'; 937 item.fixedList = [_findEntry]; 938 } 939 // @ts-ignore 940 item.highlight = item.rowId === `${Utils.getDistributedRowId(findEntry.cpu)}`; 941 item.draw(true); 942 } 943 ); 944 // @ts-ignore 945 sp.scrollToProcess(`${findEntry.cpu}`, '', 'cpu-data', true); 946 sp.onClickHandler(TraceRow.ROW_TYPE_CPU); 947} 948function findEntryTypeFunc(sp: SpSystemTrace, findEntry: unknown): void { 949 sp.observerScrollHeightEnable = true; 950 sp.scrollToActFunc( 951 { 952 // @ts-ignore 953 startTs: findEntry.startTime, 954 // @ts-ignore 955 dur: findEntry.dur, 956 // @ts-ignore 957 tid: findEntry.tid, 958 // @ts-ignore 959 pid: findEntry.pid, 960 // @ts-ignore 961 depth: findEntry.depth, 962 // @ts-ignore 963 argsetid: findEntry.argsetid, 964 // @ts-ignore 965 funName: findEntry.funName, 966 // @ts-ignore 967 cookie: findEntry.cookie, 968 // @ts-ignore 969 //因异步trace分类出的rowId类型有三种,故新增row_id字段,该字段为异步方法的对应的rowId,支持搜索查询定位到该方法属于那个row,只有缓存的异步trace数据中含该字段 970 row_id: findEntry.rowId ? findEntry.rowId : null, 971 }, 972 true 973 ); 974} 975function findEntryTypeThreadProcess(sp: SpSystemTrace, findEntry: unknown): void { 976 let threadProcessRow = sp.rowsEL?.querySelectorAll<TraceRow<ThreadStruct>>('trace-row')[0]; 977 if (threadProcessRow) { 978 let filterRow = threadProcessRow.childrenList.filter( 979 // @ts-ignore 980 (row) => row.rowId === Utils.getDistributedRowId(findEntry.rowId) && row.rowId === findEntry.rowType 981 )[0]; 982 filterRow!.highlight = true; 983 // @ts-ignore 984 sp.closeAllExpandRows(Utils.getDistributedRowId(findEntry.rowParentId)); 985 // @ts-ignore 986 sp.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); 987 let completeEntry = (): void => { 988 sp.hoverStructNull(); 989 sp.selectStructNull(); 990 sp.wakeupListNull(); 991 // @ts-ignore 992 sp.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); 993 }; 994 if (filterRow!.isComplete) { 995 completeEntry(); 996 } else { 997 filterRow!.onComplete = completeEntry; 998 } 999 } 1000} 1001function findEntryTypeSdk(sp: SpSystemTrace, findEntry: unknown): void { 1002 // @ts-ignore 1003 let parentRow = sp.shadowRoot!.querySelector<TraceRow<unknown>>(`trace-row[row-type='sdk'][folder]`); 1004 if (parentRow) { 1005 let sdkRow = parentRow.childrenList.filter( 1006 // @ts-ignore 1007 (child) => child.rowId === findEntry.rowId && child.rowType === findEntry.rowType 1008 )[0]; 1009 sdkRow!.highlight = true; 1010 } 1011 sp.hoverStructNull(); 1012 sp.selectStructNull(); 1013 sp.wakeupListNull(); 1014 // @ts-ignore 1015 sp.onClickHandler(findEntry.rowType!); 1016 // @ts-ignore 1017 sp.closeAllExpandRows(findEntry.rowParentId); 1018 // @ts-ignore 1019 sp.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true); 1020} 1021async function spSystemTraceInitBuffer( 1022 sp: SpSystemTrace, 1023 param: { buf?: ArrayBuffer; Url?: string; buf2?: ArrayBuffer }, 1024 wasmConfigUri: string, 1025 progress: Function 1026): Promise<{ 1027 status: boolean; 1028 msg: string; 1029} | null> { 1030 if (param.buf) { 1031 let configJson = ''; 1032 try { 1033 configJson = await fetch(wasmConfigUri).then((res) => res.text()); 1034 } catch (e) { 1035 error('getWasmConfigFailed', e); 1036 } 1037 let parseConfig = FlagsConfig.getSpTraceStreamParseConfig(); 1038 let { status, msg, sdkConfigMap } = await threadPool.initSqlite(param.buf, parseConfig, configJson, progress); 1039 if (!status) { 1040 return { status: false, msg: msg }; 1041 } 1042 SpSystemTrace.SDK_CONFIG_MAP = sdkConfigMap; 1043 if (param.buf2) { 1044 let { status, msg } = await threadPool2.initSqlite(param.buf2, parseConfig, configJson, progress); 1045 if (!status) { 1046 return { status: false, msg: msg }; 1047 } 1048 } 1049 return null; 1050 } else { 1051 return null; 1052 } 1053} 1054async function spSystemTraceInitUrl( 1055 sp: SpSystemTrace, 1056 param: { buf?: ArrayBuffer; url?: string }, 1057 wasmConfigUri: string, 1058 progress: Function 1059): Promise<{ 1060 status: boolean; 1061 msg: string; 1062} | null> { 1063 if (param.url) { 1064 let { status, msg } = await threadPool.initServer(param.url, progress); 1065 if (!status) { 1066 return { status: false, msg: msg }; 1067 } else { 1068 return null; 1069 } 1070 } else { 1071 return null; 1072 } 1073} 1074export async function spSystemTraceInit( 1075 sp: SpSystemTrace, 1076 param: { buf?: ArrayBuffer; url?: string; buf2?: ArrayBuffer; fileName1?: string; fileName2?: string }, 1077 wasmConfigUri: string, 1078 progress: Function, 1079 isDistributed: boolean 1080): Promise<unknown> { 1081 progress('Load database', 6); 1082 sp.rowsPaneEL!.scroll({ top: 0, left: 0 }); 1083 let rsBuf = await spSystemTraceInitBuffer(sp, param, wasmConfigUri, progress); 1084 if (rsBuf) { 1085 return rsBuf; 1086 } 1087 let rsUrl = await spSystemTraceInitUrl(sp, param, wasmConfigUri, progress); 1088 if (rsUrl) { 1089 return rsUrl; 1090 } 1091 if (isDistributed) { 1092 await sp.chartManager?.initDistributedChart(progress, param.fileName1 || 'Trace 1', param.fileName2 || 'Trace 2'); 1093 } else { 1094 await sp.chartManager?.init(progress); 1095 } 1096 let rowId: string = ''; 1097 // @ts-ignore 1098 sp.rowsEL?.querySelectorAll<TraceRow<unknown>>('trace-row').forEach((it) => { 1099 if (it.name.includes('Ark Ts')) { 1100 rowId = it.rowId!; 1101 } 1102 if (it.folder) { 1103 it.addEventListener('expansion-change', sp.extracted(it)); 1104 } 1105 }); 1106 progress('completed', 100); 1107 info('All TraceRow Data initialized'); 1108 sp.loadTraceCompleted = true; 1109 // @ts-ignore 1110 sp.rowsEL!.querySelectorAll<TraceRow<unknown>>('trace-row').forEach((it) => { 1111 if (rowId !== '' && (it.rowId?.includes(rowId) || it.name.includes(rowId))) { 1112 it.addTemplateTypes('Ark Ts'); 1113 for (let child of it.childrenList) { 1114 child.addTemplateTypes('Ark Ts'); 1115 } 1116 } 1117 if (it.folder) { 1118 let offsetYTimeOut: unknown = undefined; 1119 it.addEventListener('expansion-change', expansionChangeHandler(sp, offsetYTimeOut)); 1120 } 1121 if (sp.loadTraceCompleted) { 1122 sp.traceSheetEL?.displaySystemLogsData(); 1123 sp.traceSheetEL?.displayHangsData(); 1124 sp.traceSheetEL?.displaySystemStatesData(); 1125 } 1126 sp.intersectionObserver?.observe(it); 1127 }); 1128 // trace文件加载完毕,将动效json文件读取并存入缓存 1129 let funDetailUrl = `https://${window.location.host.split(':')[0]}:${window.location.port 1130 }/application/doc/funDetail.json`; 1131 let xhr = new XMLHttpRequest(); 1132 // 创建XMLHttpRequest对象 1133 xhr.open('GET', funDetailUrl); 1134 xhr.onreadystatechange = function (): void { 1135 if (xhr.readyState === 4 && xhr.status === 200) { 1136 let content = xhr.responseText; 1137 caches.open('/funDetail').then((cache) => { 1138 let headers = new Headers(); 1139 headers.append('Content-Type', 'application/json'); 1140 return cache 1141 .put( 1142 '/funDetail', 1143 new Response(content, { 1144 status: 200, 1145 headers, 1146 }) 1147 ) 1148 .then(); 1149 }); 1150 } 1151 }; 1152 xhr.send(); // 发送请求 1153 return { status: true, msg: 'success' }; 1154} 1155function expansionChangeHandler(sp: SpSystemTrace, offsetYTimeOut: unknown): (event: unknown) => void { 1156 return function (event: unknown) { 1157 let max = [...sp.rowsPaneEL!.querySelectorAll('trace-row')].reduce((pre, cur) => pre + cur.clientHeight!, 0); 1158 let offset = sp.rowsPaneEL!.scrollHeight - max; 1159 sp.rowsPaneEL!.scrollTop = sp.rowsPaneEL!.scrollTop - offset; 1160 JankStruct.delJankLineFlag = false; 1161 if (offsetYTimeOut) { 1162 // @ts-ignore 1163 clearTimeout(offsetYTimeOut); 1164 } 1165 // @ts-ignore 1166 if (event.detail.expansion) { 1167 offsetYTimeOut = setTimeout(() => { 1168 sp.linkNodes.forEach((linkNode) => { 1169 JankStruct.selectJankStructList?.forEach((selectStruct: unknown) => { 1170 // @ts-ignore 1171 if (event.detail.rowId === selectStruct.pid) { 1172 // @ts-ignore 1173 JankStruct.selectJankStruct = selectStruct; 1174 // @ts-ignore 1175 JankStruct.hoverJankStruct = selectStruct; 1176 } 1177 }); 1178 linkNodeHandler(linkNode, sp); 1179 }); 1180 }, 300); 1181 } else { 1182 if (JankStruct!.selectJankStruct) { 1183 JankStruct.selectJankStructList?.push(<JankStruct>JankStruct!.selectJankStruct); 1184 } 1185 offsetYTimeOut = setTimeout(() => { 1186 sp.linkNodes?.forEach((linkNode) => linkNodeHandler(linkNode, sp)); 1187 }, 300); 1188 } 1189 let refreshTimeOut = setTimeout(() => { 1190 sp.refreshCanvas(true); 1191 clearTimeout(refreshTimeOut); 1192 }, 360); 1193 }; 1194} 1195function linkNodeHandler(linkNode: PairPoint[], sp: SpSystemTrace): void { 1196 if (linkNode[0].rowEL.collect) { 1197 linkNode[0].rowEL.translateY = linkNode[0].rowEL.getBoundingClientRect().top - 195; 1198 } else { 1199 linkNode[0].rowEL.translateY = linkNode[0].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 1200 } 1201 linkNode[0].y = linkNode[0].rowEL!.translateY! + linkNode[0].offsetY; 1202 if (linkNode[1].rowEL.collect) { 1203 linkNode[1].rowEL.translateY = linkNode[1].rowEL.getBoundingClientRect().top - 195; 1204 } else { 1205 linkNode[1].rowEL.translateY = linkNode[1].rowEL.offsetTop - sp.rowsPaneEL!.scrollTop; 1206 } 1207 linkNode[1].y = linkNode[1].rowEL!.translateY! + linkNode[1].offsetY; 1208} 1209 1210const eventMap = { 1211 'cpu-data': 'Cpu', 1212 'cpu-state': 'Cpu State', 1213 'cpu-freq': 'Cpu Frequency', 1214 'cpu-limit-freq': 'Cpu Freq Limit', 1215 process: 'Process', 1216 'native-memory': 'Native Memory', 1217 thread: 'Thread', 1218 func: 'Func', 1219 mem: 'Memory', 1220 'virtual-memory-cell': 'Virtual Memory', 1221 'virtual-memory-group': 'Virtual Memory', 1222 fps: 'FPS', 1223 'ability-monitor': 'Ability Monitor', 1224 'cpu-ability': 'Cpu Ability', 1225 'memory-ability': 'Memory Ability', 1226 'disk-ability': 'DiskIO Ability', 1227 'network-ability': 'Network Ability', 1228 sdk: 'Sdk', 1229 'sdk-counter': 'SDK Counter', 1230 'sdk-slice': 'Sdk Slice', 1231 energy: 'Energy', 1232 'power-energy': 'Power Event', 1233 'system-energy': 'System Event', 1234 'anomaly-energy': 'Anomaly Event', 1235 'clock-group': 'Clocks', 1236 clock: 'clock', 1237 'irq-group': 'Irqs', 1238 irq: 'irq', 1239 hiperf: 'HiPerf (All)', 1240 'hiperf-event': 'HiPerf Event', 1241 'hiperf-report': 'HiPerf Report', 1242 'hiperf-process': 'HiPerf Process', 1243 'hiperf-thread': 'HiPerf Thread', 1244 'js-memory': 'Js Memory', 1245}; 1246export function spSystemTraceInitPointToEvent(sp: SpSystemTrace): void { 1247 sp.eventMap = eventMap; 1248} 1249 1250export function spSystemTraceParentRowSticky(sp: SpSystemTrace, deltaY: number): void { 1251 if (deltaY > 0) { 1252 // 从上往下划 1253 const expandRowList = sp.visibleRows.filter((vr) => vr.expansion); 1254 // @ts-ignore 1255 expandRowList.forEach((vr: TraceRow<unknown>) => { 1256 // @ts-ignore 1257 const visibleNotCollectList = vr.childrenList.filter((child: TraceRow<unknown>) => !child.collect && !child.sleeping); 1258 vr.sticky = visibleNotCollectList.length > 0; 1259 }); 1260 } else if (deltaY < 0) { 1261 // 从下往上划 1262 sp.visibleRows 1263 .filter((vr) => !vr.folder && vr.parentRowEl && vr.parentRowEl.expansion && !vr.collect) 1264 .forEach((vr) => (vr.parentRowEl!.sticky = true)); 1265 } else { 1266 return; 1267 } 1268} 1269