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'; 17import { type LitTabs } from '../../../../base-ui/tabs/lit-tabs'; 18import { LitTabpane } from '../../../../base-ui/tabs/lit-tabpane'; 19import { 20 BoxJumpParam, 21 SelectionParam, 22 SysCallBoxJumpParam, 23 SliceBoxJumpParam, 24 PerfSampleBoxJumpParam 25} from '../../../bean/BoxSelection'; 26import { type TabPaneCurrentSelection } from '../sheet/TabPaneCurrentSelection'; 27import { type TabPaneFlag } from '../timer-shaft/TabPaneFlag'; 28import { type Flag } from '../timer-shaft/Flag'; 29import { type WakeupBean } from '../../../bean/WakeupBean'; 30import { type LitIcon } from '../../../../base-ui/icon/LitIcon'; 31import { tabConfig } from './TraceSheetConfig'; 32import { type TabPaneBoxChild } from '../sheet/cpu/TabPaneBoxChild'; 33import { type CpuStruct } from '../../../database/ui-worker/cpu/ProcedureWorkerCPU'; 34import { CpuFreqStruct } from '../../../database/ui-worker/ProcedureWorkerFreq'; 35import { CpuFreqLimitsStruct } from '../../../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits'; 36import { type ThreadStruct } from '../../../database/ui-worker/ProcedureWorkerThread'; 37import { type ThreadSysCallStruct } from '../../../database/ui-worker/ProcedureWorkerThreadSysCall'; 38import { type FuncStruct } from '../../../database/ui-worker/ProcedureWorkerFunc'; 39import { ProcessMemStruct } from '../../../database/ui-worker/ProcedureWorkerMem'; 40import { CpuStateStruct } from '../../../database/ui-worker/cpu/ProcedureWorkerCpuState'; 41import { type HangStruct } from '../../../database/ui-worker/ProcedureWorkerHang'; 42import { type ClockStruct } from '../../../database/ui-worker/ProcedureWorkerClock'; 43import { type DmaFenceStruct } from '../../../database/ui-worker/ProcedureWorkerDmaFence'; 44import { type XpowerStruct } from '../../../database/ui-worker/ProcedureWorkerXpower'; 45import { type IrqStruct } from '../../../database/ui-worker/ProcedureWorkerIrq'; 46import { type JankStruct } from '../../../database/ui-worker/ProcedureWorkerJank'; 47import { type HeapStruct } from '../../../database/ui-worker/ProcedureWorkerHeap'; 48import { type LitTable } from '../../../../base-ui/table/lit-table'; 49import { threadPool } from '../../../database/SqlLite'; 50import { type HeapSnapshotStruct } from '../../../database/ui-worker/ProcedureWorkerHeapSnapshot'; 51import { type TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneNMStatisticAnalysis'; 52import { type TabPaneCurrent } from '../sheet/TabPaneCurrent'; 53import { type SlicesTime } from '../timer-shaft/SportRuler'; 54import { type AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup'; 55import { type AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup'; 56import { type SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit'; 57import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation'; 58import { type TraceRow } from './TraceRow'; 59import { type FrameDynamicStruct } from '../../../database/ui-worker/ProcedureWorkerFrameDynamic'; 60import { type TabPaneFrameDynamic } from '../sheet/frame/TabPaneFrameDynamic'; 61import { type FrameSpacingStruct } from '../../../database/ui-worker/ProcedureWorkerFrameSpacing'; 62import { type TabFrameSpacing } from '../sheet/frame/TabFrameSpacing'; 63import { type JsCpuProfilerChartFrame } from '../../../bean/JsStruct'; 64import { type TabPaneComparison } from '../sheet/ark-ts/TabPaneComparison'; 65import { type TabPaneSummary } from '../sheet/ark-ts/TabPaneSummary'; 66import { type TabPaneGpuClickSelect } from '../sheet/gpu/TabPaneGpuClickSelect'; 67import { type TabPanePurgTotalSelection } from '../sheet/ability/TabPanePurgTotalSelection'; 68import { type TabPanePurgPinSelection } from '../sheet/ability/TabPanePurgPinSelection'; 69import { type TabPaneVmTrackerShmSelection } from '../sheet/vmtracker/TabPaneVmTrackerShmSelection'; 70import { type TabPaneSmapsStatistics } from '../sheet/smaps/TabPaneSmapsStatistics'; 71import { type TabPaneSmapsComparison } from '../sheet/smaps/TabPaneSmapsComparison'; 72import { type SnapshotStruct } from '../../../database/ui-worker/ProcedureWorkerSnapshot'; 73import { type TabPaneDmaSelectAbility } from '../sheet/ability/TabPaneDmaSelectAbility'; 74import { type TabPaneGpuMemorySelectAbility } from '../sheet/ability/TabPaneGpuMemorySelectAbility'; 75import { type TabPaneDmaSelectVmTracker } from '../sheet/vmtracker/TabPaneDmaSelectVmTracker'; 76import { type TabPanePurgTotalComparisonAbility } from '../sheet/ability/TabPanePurgTotalComparisonAbility'; 77import { type TabPanePurgPinComparisonAbility } from '../sheet/ability/TabPanePurgPinComparisonAbility'; 78import { type TabPanePurgTotalComparisonVM } from '../sheet/vmtracker/TabPanePurgTotalComparisonVM'; 79import { type TabPanePurgPinComparisonVM } from '../sheet/vmtracker/TabPanePurgPinComparisonVM'; 80import { type TabPaneDmaAbilityComparison } from '../sheet/ability/TabPaneDmaAbilityComparison'; 81import { type TabPaneGpuMemoryComparison } from '../sheet/ability/TabPaneGpuMemoryComparison'; 82import { type TabPaneDmaVmTrackerComparison } from '../sheet/vmtracker/TabPaneDmaVmTrackerComparison'; 83import { type TabPaneGpuMemorySelectVmTracker } from '../sheet/vmtracker/TabPaneGpuMemorySelectVmTracker'; 84import { type TabPaneGpuMemoryVmTrackerComparison } from '../sheet/vmtracker/TabPaneGpuMemoryVmTrackerComparison'; 85import { type TabPaneVmTrackerShmComparison } from '../sheet/vmtracker/TabPaneVmTrackerShmComparison'; 86import { type TabPaneJsCpuStatistics } from '../sheet/ark-ts/TabPaneJsCpuStatistics'; 87import { type TabPaneGpuClickSelectComparison } from '../sheet/gpu/TabPaneGpuClickSelectComparison'; 88import { Utils } from './Utils'; 89import { TabPaneHiLogs } from '../sheet/hilog/TabPaneHiLogs'; 90import { TabPaneGpuResourceVmTracker } from '../sheet/vmtracker/TabPaneGpuResourceVmTracker'; 91import { type LitPageTable } from '../../../../base-ui/table/LitPageTable'; 92import '../../../../base-ui/popover/LitPopoverV'; 93import { LitPopover } from '../../../../base-ui/popover/LitPopoverV'; 94import { LitTree, TreeItemData } from '../../../../base-ui/tree/LitTree'; 95import { SampleStruct } from '../../../database/ui-worker/ProcedureWorkerBpftrace'; 96import { TabPaneUserPlugin } from '../sheet/userPlugin/TabPaneUserPlugin'; 97import { TabPaneSampleInstruction } from '../sheet/bpftrace/TabPaneSampleInstruction'; 98import { TabPaneFreqStatesDataCut } from '../sheet/states/TabPaneFreqStatesDataCut'; 99import { TabPaneDataCut } from '../sheet/TabPaneDataCut'; 100import { SpSystemTrace } from '../../SpSystemTrace'; 101import { PerfToolStruct } from '../../../database/ui-worker/ProcedureWorkerPerfTool'; 102import { GpuCounterStruct } from '../../../database/ui-worker/ProcedureWorkerGpuCounter'; 103import { TabPaneGpuCounter } from '../sheet/gpu-counter/TabPaneGpuCounter'; 104import { TabPaneSliceChild } from '../sheet/process/TabPaneSliceChild'; 105import { TabPerfFuncAsm } from '../sheet/hiperf/TabPerfFuncAsm'; 106import { XpowerStatisticStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerStatistic'; 107import { XpowerAppDetailStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerAppDetail'; 108import { XpowerWifiStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerWifi'; 109import { TabPaneXpowerStatisticCurrentData } from '../sheet/xpower/TabPaneXpowerStatisticCurrentData'; 110import { XpowerThreadInfoStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerThreadInfo'; 111import { TabPaneXpowerThreadInfoSelection } from '../sheet/xpower/TabPaneXpowerThreadInfoSelection'; 112import { TabPaneXpowerGpuFreqSelection } from '../sheet/xpower/TabPaneXpowerGpuFreqSelection'; 113import { XpowerGpuFreqStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerGpuFreq'; 114import { WebSocketManager } from '../../../../webSocket/WebSocketManager'; 115import { Constants, TypeConstants } from '../../../../webSocket/Constants'; 116import { PerfFunctionAsmParam } from '../../../bean/PerfAnalysis'; 117import { info, error } from '../../../../log/Log'; 118import { XpowerThreadCountStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerThreadCount'; 119import { XpowerGpuFreqCountStruct } from '../../../database/ui-worker/ProcedureWorkerXpowerGpuFreqCount'; 120import { TabPaneSysCallChild } from '../sheet/process/TabPaneSysCallChild'; 121import { TabPanePerfSampleChild } from '../sheet/hiperf/TabPerfSampleChild'; 122 123 124@element('trace-sheet') 125export class TraceSheet extends BaseElement { 126 systemLogFlag: Flag | undefined | null; 127 private litTabs: LitTabs | undefined | null; 128 private switchDiv: LitPopover | undefined | null; 129 private processTree: LitTree | undefined | null; 130 private importDiv: HTMLDivElement | undefined | null; 131 private symbolDiv: HTMLDivElement | undefined | null; 132 private exportBt: LitIcon | undefined | null; 133 private nav: HTMLDivElement | undefined | null; 134 private tabs: HTMLDivElement | undefined | null; 135 private navRoot: HTMLDivElement | null | undefined; 136 private search: HTMLDivElement | undefined | null; 137 private timerShaft: HTMLDivElement | undefined | null; 138 private spacer: HTMLDivElement | undefined | null; 139 private rowsPaneEL: HTMLDivElement | undefined | null; 140 private selection: SelectionParam | undefined | null; 141 private currentPaneID: string = 'current-selection'; 142 private fragment: DocumentFragment | undefined; 143 private lastSelectIPid: number = -1; 144 private lastProcessSet: Set<number> = new Set<number>(); 145 private optionsDiv: LitPopover | undefined | null; 146 private optionsSettingTree: LitTree | undefined | null; 147 private tabPaneHeight: string = ''; 148 private spsystemTrace: SpSystemTrace | undefined; 149 private isDragging = true; 150 private REQ_BUF_SIZE = 1024 * 1024; 151 private loadSoComplete = false; 152 153 static get observedAttributes(): string[] { 154 return ['mode']; 155 } 156 157 buildTabs(litTabs: LitTabs | undefined | null): void { 158 this.fragment = document.createDocumentFragment(); // @ts-ignore 159 Reflect.ownKeys(tabConfig).forEach((key, index): void => { 160 let pane = new LitTabpane(); 161 pane.id = key.toString(); 162 pane.className = 'tabHeight'; // @ts-ignore 163 pane.tab = tabConfig[key].title; 164 pane.hidden = true; // @ts-ignore 165 pane.key = `${tabConfig[key].key || index}`; // @ts-ignore 166 let cls = tabConfig[key].type; 167 // @ts-ignore 168 let node = new cls(); 169 pane.append(node); 170 this.fragment?.appendChild(pane); 171 }); 172 litTabs!.appendChild(this.fragment); 173 } 174 175 displayTab<T>(...names: string[]): T { 176 this.setMode('max'); 177 this.showOptionsBt(this.selection); 178 this.showUploadSoBt(this.selection); 179 this.showSwitchProcessBt(this.selection); 180 this.shadowRoot 181 ?.querySelectorAll<LitTabpane>('#tabs lit-tabpane') 182 .forEach((it) => (it.hidden = !names.some((k) => k === it.id))); 183 let litTabpane = this.shadowRoot?.querySelector<LitTabpane>(`#tabs lit-tabpane[id='${names[0]}']`); 184 if (names[0] === 'current-selection') { 185 this.exportBt!.style.display = 'none'; 186 } else { 187 this.exportBt!.style.display = 'flex'; 188 } 189 this.shadowRoot?.querySelector<LitTabs>('#tabs')?.activePane(litTabpane!.key); 190 return litTabpane!.children.item(0) as unknown as T; 191 } 192 193 getComponentByID<T>(id: string): T { 194 return this.getPaneByID(id)?.children.item(0) as unknown as T; 195 } 196 197 getPaneByID(id: string): LitTabpane { 198 return this.shadowRoot!.querySelector(`#${id}`)!; 199 } 200 201 initElements(): void { 202 this.spsystemTrace = document.querySelector("body > sp-application")?.shadowRoot?.querySelector("#sp-system-trace") as SpSystemTrace; 203 this.litTabs = this.shadowRoot?.querySelector('#tabs'); 204 this.litTabs!.addEventListener('contextmenu', (e): void => { 205 e.preventDefault(); 206 }); 207 this.importDiv = this.shadowRoot?.querySelector('#import_div'); 208 this.symbolDiv = this.shadowRoot?.querySelector('#symbol_div'); 209 this.switchDiv = this.shadowRoot?.querySelector('#select-process'); 210 this.processTree = this.shadowRoot?.querySelector('#processTree'); 211 this.optionsDiv = this.shadowRoot?.querySelector('#options'); 212 this.optionsSettingTree = this.shadowRoot?.querySelector('#optionsSettingTree'); 213 this.optionsSettingTree!.onChange = (e: unknown): void => { 214 const select = this.optionsSettingTree!.getCheckdKeys(); 215 document.dispatchEvent( 216 new CustomEvent('sample-popver-change', { 217 detail: { 218 select: select[0], 219 }, 220 }) 221 ); 222 }; 223 this.processTree!.onChange = (e: unknown): void => { 224 const select = this.processTree!.getCheckdKeys(); 225 const selectIPid = Number(select[0]); 226 this.switchDiv!.visible = 'false'; 227 this.updateRangeSelect(selectIPid); 228 this.lastSelectIPid = selectIPid; 229 }; 230 this.buildTabs(this.litTabs); // @ts-ignore 231 this.litTabs!.onTabClick = (e: unknown): void => this.loadTabPaneData(e.detail.key); 232 this.tableCloseHandler(); 233 this.rowClickEvent(); 234 this.tdClickEvent(); 235 } 236 private rowClickEvent(): void { 237 // @ts-ignore 238 this.getComponentByID<unknown>('box-perf-analysis')?.addEventListener('row-click', (evt: MouseEvent) => { 239 this.perfAnalysisListener(evt); 240 }); 241 // @ts-ignore 242 this.getComponentByID<unknown>('box-perf-analysis')?.addFunctionRowClickEventListener(this.functionAnalysisListener.bind(this)); 243 // @ts-ignore 244 this.getComponentByID<unknown>('box-native-statistic-analysis')?.addEventListener('row-click', (e: MouseEvent) => { 245 this.nativeAnalysisListener(e); 246 }); 247 // @ts-ignore 248 this.getComponentByID<unknown>('box-io-tier-statistics-analysis')?.addEventListener( 249 'row-click', 250 (evt: MouseEvent) => { 251 // @ts-ignore 252 if (evt.detail.button === 2 && evt.detail.tableName) { 253 let pane = this.getPaneByID('box-io-calltree'); 254 this.litTabs!.activeByKey(pane.key); 255 } 256 } 257 ); 258 // @ts-ignore 259 this.getComponentByID<unknown>('box-virtual-memory-statistics-analysis')?.addEventListener( 260 'row-click', 261 (evt: MouseEvent) => { 262 // @ts-ignore 263 if (evt.detail.button === 2 && evt.detail.tableName) { 264 let pane = this.getPaneByID('box-vm-calltree'); 265 this.litTabs!.activeByKey(pane.key); 266 } 267 } 268 ); 269 // @ts-ignore 270 this.getComponentByID<unknown>('box-file-system-statistics-analysis')?.addEventListener( 271 'row-click', 272 (evt: MouseEvent) => { 273 // @ts-ignore 274 if (evt.detail.button === 2 && evt.detail.tableName) { 275 let pane = this.getPaneByID('box-file-system-calltree'); 276 this.litTabs!.activeByKey(pane.key); 277 } 278 } 279 ); 280 // @ts-ignore 281 this.getComponentByID<unknown>('box-native-statstics')?.addEventListener('row-click', (e: unknown) => { 282 this.nativeStatsticsListener(e); 283 }); 284 // @ts-ignore 285 this.getComponentByID<unknown>('box-virtual-memory-statistics')?.addEventListener('row-click', (e: unknown) => { 286 this.virtualMemoryListener(e); 287 }); 288 // @ts-ignore 289 this.getComponentByID<unknown>('box-io-tier-statistics')?.addEventListener('row-click', (e: unknown) => { 290 this.ioTierListener(e); 291 }); 292 // @ts-ignore 293 this.getComponentByID<unknown>('box-file-system-statistics')?.addEventListener('row-click', (e: unknown) => { 294 this.fileSystemListener(e); 295 }); 296 } 297 298 private tdClickEvent(): void { 299 // @ts-ignore 300 this.getComponentByID<unknown>('box-spt')?.addEventListener('td-click', (evt: unknown) => { 301 this.tdClickHandler(evt, true); 302 }); 303 // @ts-ignore 304 this.getComponentByID<unknown>('box-pts')?.addEventListener('td-click', (evt: unknown) => { 305 this.tdClickHandler(evt, true); 306 }); 307 // @ts-ignore 308 this.getComponentByID<unknown>('box-thread-states')?.addEventListener('td-click', (evt: unknown) => { 309 this.tdClickHandler(evt); 310 }); 311 // @ts-ignore 312 this.getComponentByID<unknown>('box-slices')?.addEventListener('td-click', (evt: unknown) => { 313 this.tdSliceClickHandler(evt); 314 }); 315 // @ts-ignore 316 this.getComponentByID<unknown>('box-thread-syscall')?.addEventListener('td-click', (evt: unknown) => { 317 this.tdSysCallClickHandler(evt); 318 }); 319 // @ts-ignore 320 this.getComponentByID<unknown>('box-perf-profile')?.addEventListener('td-click', (evt: unknown) => { 321 this.tdPerfSampleClickHandler(evt); 322 }); 323 } 324 325 private perfAnalysisListener(evt: MouseEvent): void { 326 // @ts-ignore 327 if (evt.detail.button === 2 && evt.detail.pid) { 328 let pane = this.getPaneByID('box-perf-profile'); 329 this.litTabs!.activeByKey(pane.key); 330 } 331 } 332 333 private functionAnalysisListener(evt: unknown, vaddrList: Array<unknown>): void { 334 // @ts-ignore 335 this.currentPaneID = 'box-perf-analysis'; 336 //隐藏除了当前Tab页的其他Tab页 337 this.shadowRoot!.querySelectorAll<LitTabpane>('lit-tabpane').forEach( 338 (it)=>{ 339 if(it.id === this.currentPaneID) { 340 it.hidden = false; 341 } 342 } 343 ); 344 let asmPane = this.getPaneByID('tab-perf-func-asm'); //通过Id找到需要展示的Tab页 345 asmPane.closeable = true; 346 asmPane.hidden = false; 347 // @ts-ignore 348 asmPane.tab = evt.tableName; //设置Tab页标题 349 let param = new PerfFunctionAsmParam(); 350 param.vaddrList = vaddrList; 351 // @ts-ignore 352 param.functionName = evt.tableName; 353 // @ts-ignore 354 param.totalCount = evt.count; 355 (asmPane.children.item(0) as TabPerfFuncAsm)!.data = param; 356 this.litTabs!.activeByKey(asmPane.key); //显示key值(sheetconfig里面对应的index是一个数字)对应的Tab页 357 } 358 359 private nativeAnalysisListener(e: MouseEvent): void { 360 //@ts-ignore 361 if (e.detail.button === 2 && e.detail.tableName) { 362 let pane = this.getPaneByID('box-native-calltree'); 363 pane.hidden = false; 364 this.litTabs!.activeByKey(pane.key); 365 } 366 } 367 368 private nativeStatsticsListener(e: unknown): void { 369 // @ts-ignore 370 if (e.detail.button === 0) { 371 // @ts-ignore 372 this.selection!.statisticsSelectData = e.detail; 373 let pane = this.getPaneByID('box-native-memory'); 374 this.litTabs?.activeByKey(pane.key); 375 // @ts-ignore 376 (pane.children.item(0) as unknown)!.fromStastics(this.selection); 377 } 378 } 379 380 private virtualMemoryListener(e: unknown): void { 381 // @ts-ignore 382 if (e.detail.button === 0) { 383 // @ts-ignore 384 this.selection!.fileSystemVMData = { path: e.detail.path }; 385 let pane = this.getPaneByID('box-vm-events'); 386 this.litTabs?.activeByKey(pane.key); 387 // @ts-ignore 388 if (e.detail.path) { 389 // @ts-ignore 390 (pane.children.item(0) as unknown)!.fromStastics(this.selection); 391 } 392 } 393 } 394 395 private ioTierListener(e: unknown): void { 396 // @ts-ignore 397 if (e.detail.button === 0) { 398 // @ts-ignore 399 this.selection!.fileSystemIoData = { path: e.detail.path }; 400 let pane = this.getPaneByID('box-io-events'); 401 this.litTabs?.activeByKey(pane.key); 402 // @ts-ignore 403 if (e.detail.path) { 404 // @ts-ignore 405 (pane.children.item(0) as unknown)!.fromStastics(this.selection); 406 } 407 } 408 } 409 410 private fileSystemListener(e: unknown): void { 411 // @ts-ignore 412 if (e.detail.button === 0) { 413 // @ts-ignore 414 this.selection!.fileSystemFsData = e.detail.data; 415 let pane = this.getPaneByID('box-file-system-event'); 416 this.litTabs?.activeByKey(pane.key); 417 // @ts-ignore 418 if (e.detail.data) { 419 // @ts-ignore 420 (pane.children.item(0) as unknown)!.fromStastics(this.selection); 421 } 422 } 423 } 424 425 private tableCloseHandler(): void { 426 this.litTabs!.addEventListener('close-handler', () => { 427 // @ts-ignore 428 Reflect.ownKeys(tabConfig) 429 .reverse() 430 .forEach((id) => { 431 // @ts-ignore 432 let element = tabConfig[id]; 433 let pane = this.shadowRoot!.querySelector<LitTabpane>(`#${id as string}`); 434 if (element.require) { 435 pane!.hidden = !element.require(this.selection!); 436 } else { 437 pane!.hidden = true; 438 } 439 }); 440 this.litTabs?.activeByKey(`${this.getPaneByID(this.currentPaneID).key}`); 441 }); 442 } 443 444 connectedCallback(): void { 445 this.nav = this.shadowRoot?.querySelector('#tabs')?.shadowRoot?.querySelector('.tab-nav-vessel'); 446 this.tabs = this.shadowRoot?.querySelector('#tabs'); 447 this.navRoot = this.shadowRoot?.querySelector('#tabs')?.shadowRoot?.querySelector('.nav-root'); 448 this.search = document.querySelector('body > sp-application')?.shadowRoot?.querySelector('div > div.search-vessel'); 449 this.timerShaft = this.parentElement?.querySelector('.timer-shaft'); 450 this.spacer = this.parentElement?.querySelector('.spacer'); 451 this.rowsPaneEL = this.parentElement?.querySelector('.rows-pane'); 452 let tabsOpenUp: LitIcon | undefined | null = this.shadowRoot?.querySelector<LitIcon>('#max-btn'); 453 let tabsPackUp: LitIcon | undefined | null = this.shadowRoot?.querySelector<LitIcon>('#min-btn'); 454 let borderTop: number = 1; 455 let initialHeight = { tabs: 'calc(30vh + 39px)', node: '30vh' }; 456 this.initNavElements(tabsPackUp!, borderTop, initialHeight); 457 this.exportBt = this.shadowRoot?.querySelector<LitIcon>('#export-btn'); 458 tabsOpenUp!.onclick = (): void => { 459 this.tabs!.style.height = `${window.innerHeight - this.search!.offsetHeight - this.timerShaft!.offsetHeight - borderTop 460 }px`; 461 let litTabpane: NodeListOf<HTMLDivElement> | undefined | null = 462 this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); 463 litTabpane!.forEach((node: HTMLDivElement): void => { 464 node!.style.height = `${window.innerHeight - 465 this.search!.offsetHeight - 466 this.timerShaft!.offsetHeight - 467 this.navRoot!.offsetHeight - 468 borderTop 469 }px`; 470 initialHeight.node = node!.style.height; 471 }); 472 initialHeight.tabs = this.tabs!.style.height; 473 tabsPackUp!.name = 'down'; 474 }; 475 tabsPackUp!.onclick = (): void => { 476 let litTabpane: NodeListOf<HTMLDivElement> | undefined | null = 477 this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); 478 if (tabsPackUp!.name === 'down') { 479 let beforeHeight = this.clientHeight; 480 this.tabs!.style.height = `${this.navRoot!.offsetHeight}px`; 481 window.publish(window.SmartEvent.UI.ShowBottomTab, { show: 2, delta: beforeHeight - this.clientHeight }); 482 litTabpane!.forEach((node: HTMLDivElement) => (node!.style.height = '0px')); 483 tabsPackUp!.name = 'up'; 484 tabsPackUp!.title = 'Reset Tab'; // @ts-ignore 485 (window as unknown).isPackUpTable = true; 486 } else { 487 tabsPackUp!.name = 'down'; 488 tabsPackUp!.title = 'Minimize Tab'; 489 this.tabs!.style.height = initialHeight.tabs; 490 litTabpane!.forEach((node: HTMLDivElement) => (node!.style.height = initialHeight.node)); 491 } 492 }; 493 this.importClickEvent(); 494 this.exportClickEvent(); 495 } 496 497 private initNavElements(tabsPackUp: LitIcon, borderTop: number, initialHeight: { node: string; tabs: string }): void { 498 let that = this; 499 // 节点挂载时给Tab面板绑定鼠标按下事件 500 this.nav!.onmousedown = (event): void => { 501 this.isDragging = true; 502 // @ts-ignore 503 (window as unknown).isSheetMove = true; 504 // 获取所有标签页的节点数组 505 let litTabpane: NodeListOf<HTMLDivElement> | undefined | null = 506 this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); 507 // 获取当前选中面板的key值,后续用来确定当前面板是哪一个。 对于用户来说,直观看到的只有当前面板,其他面板可以在拖动完成后一次性设置好新的高度 508 // @ts-ignore 509 let litTabNavKey: string = this.nav!.querySelector('.nav-item[data-selected=true]').dataset.key; 510 let currentPane: HTMLDivElement = this.shadowRoot?.querySelector(`#tabs > lit-tabpane[key="${litTabNavKey}"]`)!; 511 // 原函数 绑定鼠标移动事件,动态获取鼠标位置信息 512 this.navMouseMove(event, currentPane!, that, tabsPackUp, borderTop); 513 document.onmouseup = function (): void { 514 that.isDragging = true; 515 setTimeout(() => { 516 // @ts-ignore 517 (window as unknown).isSheetMove = false; 518 }, 100); 519 litTabpane!.forEach((node: HTMLDivElement): void => { 520 node!.style.height = that.tabPaneHeight; 521 }); 522 if (that.tabPaneHeight !== '0px' && that.tabs!.style.height !== '') { 523 // 每次都会重新记录上次拖动完成后的面板高度,下次重新显示tab页时,会以上次拖动后的高度显示 524 initialHeight.node = that.tabPaneHeight; 525 initialHeight.tabs = that.tabs!.style.height; 526 } 527 // 将绑定的事件置空,需要时重新绑定 528 this.onmousemove = null; 529 this.onmouseup = null; 530 }; 531 }; 532 this.spsystemTrace?.addEventListener('abnormal-mouseup', () => { 533 this.isDragging = false; 534 let litTabpane: NodeListOf<HTMLDivElement> | undefined | null = 535 this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); 536 setTimeout(() => { 537 // @ts-ignore 538 (window as unknown).isSheetMove = false; 539 }, 100); 540 litTabpane!.forEach((node: HTMLDivElement): void => { 541 node!.style.height = that.tabPaneHeight; 542 }); 543 if (that.tabPaneHeight !== '0px' && that.tabs!.style.height !== '') { 544 initialHeight.node = that.tabPaneHeight; 545 initialHeight.tabs = that.tabs!.style.height; 546 } 547 this.onmousemove = null; 548 this.onmouseup = null; 549 }) 550 } 551 552 private navMouseMove( 553 event: MouseEvent, 554 litTabpane: HTMLDivElement, 555 that: this, 556 tabsPackUp: LitIcon, 557 borderTop: number 558 ): void { 559 // 鼠标移动前记录此时的鼠标位置信息,后续根据新值与前次值作比对 560 let preY = event.pageY; 561 // 获取此时tab组件的偏移高度 需要包含水平滚动条的高度等 562 let preHeight = this.tabs!.offsetHeight; 563 // 获取此时整个滚动区域高度 564 let scrollH = that.rowsPaneEL!.scrollHeight; 565 // 获取此时滚动区域上方被隐藏的高度 566 let scrollT = that.rowsPaneEL!.scrollTop; 567 // 获取当前内容区高度加上上下内边距高度,即面板组件高度 568 let ch = that.clientHeight; 569 // 鼠标移动事件 570 document.onmousemove = function (event): void { 571 if (!that.isDragging) { 572 return; 573 } 574 // 移动前的面板高度 - 移动前后鼠标的坐标差值 = 新的面板高度 575 let newHeight: number = preHeight - (event.pageY - preY); 576 // that指向的是tracesheet节点 spacer为垫片 rowsPaneEl为泳道 tabs为tab页组件 577 // litTabpane为当前面板 navRoot为面板头部区的父级容器 search为顶部搜索区整个区域 578 // 这四个判断条件中,第一个尚未找到触发条件 后续和润和确认是否会触发 579 if (that.spacer!.offsetHeight > that.rowsPaneEL!.offsetHeight) { 580 that.tabs!.style.height = `${newHeight}px`; 581 litTabpane!.style.height = `${newHeight - that.navRoot!.offsetHeight}px`; 582 // 设置右上角面板大小化的箭头样式,面板在移动到最底部时,箭头向上,其余情况箭头向下 583 tabsPackUp!.name = 'down'; 584 } else if ( 585 // 只要没有移动到边界区域都会进入该条件 586 that.navRoot!.offsetHeight <= newHeight && 587 that.search!.offsetHeight + that.timerShaft!.offsetHeight + borderTop + that.spacer!.offsetHeight <= 588 window.innerHeight - newHeight 589 ) { 590 that.tabs!.style.height = `${newHeight}px`; 591 litTabpane!.style.height = `${newHeight - that.navRoot!.offsetHeight}px`; 592 tabsPackUp!.name = 'down'; 593 } else if (that.navRoot!.offsetHeight >= newHeight) { 594 // 该条件在面板置底时触发 595 that.tabs!.style.height = `${that.navRoot!.offsetHeight}px`; 596 litTabpane!.style.height = '0px'; 597 tabsPackUp!.name = 'up'; 598 } else if ( 599 that.search!.offsetHeight + that.timerShaft!.offsetHeight + borderTop + that.spacer!.offsetHeight >= 600 window.innerHeight - newHeight 601 ) { 602 // 该条件在面板高度置顶时触发 603 that.tabs!.style.height = `${window.innerHeight - 604 that.search!.offsetHeight - 605 that.timerShaft!.offsetHeight - 606 borderTop - 607 that.spacer!.offsetHeight 608 }px`; 609 litTabpane!.style.height = `${window.innerHeight - 610 that.search!.offsetHeight - 611 that.timerShaft!.offsetHeight - 612 that.navRoot!.offsetHeight - 613 borderTop - 614 that.spacer!.offsetHeight 615 }px`; 616 tabsPackUp!.name = 'down'; 617 } 618 that.tabPaneHeight = litTabpane!.style.height; 619 let currentSH = that.rowsPaneEL!.scrollHeight; 620 // 第一个判断条件尚未确定如何触发,currentSH与scrollH始终相等 621 if (currentSH > scrollH && currentSH > that.rowsPaneEL!.scrollTop + that.clientHeight) { 622 that.rowsPaneEL!.scrollTop = scrollT - (ch - that.clientHeight); 623 } 624 }; 625 } 626 627 private importClickEvent(): void { 628 let importFileBt: HTMLInputElement | undefined | null = 629 this.shadowRoot?.querySelector<HTMLInputElement>('#import-file'); 630 importFileBt!.addEventListener('change', (event): void => { 631 WebSocketManager.instance = null; 632 WebSocketManager.getInstance(); 633 let timerOut = window.setTimeout(() => { 634 window.clearTimeout(timerOut); 635 let errorTipHtml = document.querySelector('body > sp-application')?.shadowRoot?.querySelector('#sp-system-trace') 636 ?.shadowRoot?.querySelector('div > trace-sheet')?.shadowRoot?.querySelector('#box-perf-analysis > tabpane-perf-analysis')?.shadowRoot?.querySelector('#SO-err-tips'); 637 let connected = document.querySelector('body > sp-application') 638 ?.shadowRoot?.querySelector('#main-menu')?.shadowRoot?.querySelector('div.bottom > div.extend_connect') as HTMLDivElement; 639 if (connected && connected.style.backgroundColor !== 'green') { 640 errorTipHtml!.innerHTML = 'Please check if the extension service is enabled and try again!'; 641 importFileBt!.files = null; 642 importFileBt!.value = ''; 643 return; 644 } 645 let files = importFileBt?.files; 646 if (files) { 647 let fileList: Array<File> = []; 648 for (let file of files) { 649 fileList.push(file); 650 } 651 if (fileList.length > 0) { 652 importFileBt!.disabled = true; 653 this.loadSoComplete = false; 654 window.publish(window.SmartEvent.UI.Loading, { loading: true, text: 'Import So File' }); 655 this.uploadSoOrAN(fileList).then(r => { 656 errorTipHtml!.innerHTML = ''; 657 let soFileList = fileList.filter(item => !item.name.includes('.an')); 658 if (soFileList.length === 0) { 659 window.publish(window.SmartEvent.UI.UploadSOFile, {}); 660 importFileBt!.disabled = false; 661 return; 662 } 663 threadPool.submit( 664 'upload-so', 665 '', 666 soFileList, 667 (res: unknown) => { 668 importFileBt!.disabled = false; // @ts-ignore 669 if (res.result === 'ok') { 670 window.publish(window.SmartEvent.UI.UploadSOFile, {}); 671 this.loadSoComplete = true; 672 } else { 673 // @ts-ignore 674 const failedList = res.failedArray.join(','); 675 window.publish(window.SmartEvent.UI.Error, `parse so file ${failedList} failed!`); 676 } 677 }, 678 'upload-so' 679 ) 680 } 681 ).finally(() => { 682 fileList.length = 0; 683 }) 684 } 685 } 686 importFileBt!.files = null; 687 importFileBt!.value = ''; 688 }, 500) 689 }); 690 this.addClickEventToSoSymbolImport(); 691 } 692 693 private addClickEventToSoSymbolImport(): void{ 694 let symbolBt: HTMLInputElement | undefined | null = 695 this.shadowRoot?.querySelector<HTMLInputElement>('#so-symbolization'); 696 symbolBt!.addEventListener('change', (event): void => { 697 let files = symbolBt?.files; 698 if (files) { 699 let fileList: Array<File> = []; 700 for (let file of files) { 701 fileList.push(file); 702 } 703 if (fileList.length > 0) { 704 symbolBt!.disabled = true; 705 window.publish(window.SmartEvent.UI.Loading, { loading: true, text: 'Import So File' }); 706 // @ts-ignore 707 document.querySelector('body > sp-application').shadowRoot.querySelector('#sp-system-trace').shadowRoot.querySelector('div > trace-sheet').shadowRoot.querySelector('#box-perf-analysis > tabpane-perf-analysis').shadowRoot.querySelector('#SO-err-tips')?.innerHTML = ''; 708 let soFileList = fileList.filter(item => item.name.includes('.so')); 709 if (soFileList.length === 0) { 710 window.publish(window.SmartEvent.UI.UploadSOFile, {}); 711 symbolBt!.disabled = false; 712 return; 713 } 714 threadPool.submit( 715 'upload-so', 716 '', 717 soFileList, 718 (res: unknown) => { 719 symbolBt!.disabled = false; 720 setTimeout(() => { 721 // @ts-ignore 722 if (res.result === 'ok') { 723 window.publish(window.SmartEvent.UI.UploadSOFile, {}); 724 } else { 725 // @ts-ignore 726 const failedList = res.failedArray.join(','); 727 window.publish(window.SmartEvent.UI.Error, `parse so file ${failedList} failed!`); 728 } 729 }, 500); 730 }, 731 'upload-so' 732 ); 733 } 734 fileList.length = 0; 735 } 736 symbolBt!.files = null; 737 symbolBt!.value = ''; 738 }) 739 } 740 741 private async uploadSoOrAN(fileList: Array<File>): Promise<void> { 742 if (fileList) { 743 fileList.sort((a, b) => { 744 return b.size - a.size; 745 }); 746 await this.uploadAllFiles(fileList); 747 } 748 } 749 750 751 // 上传文件 752 private async uploadAllFiles(fileList: Array<File>): Promise<void> { 753 // 创建一个副本,避免修改原始的 fileList 754 const filesToUpload = [...fileList]; 755 756 for (let i = 0; i < filesToUpload.length; i++) { 757 const file = filesToUpload[i]; 758 try { 759 await this.uploadSingleFile(file); 760 info(`File ${file.name} uploaded successfully.`); 761 } catch (err) { 762 error(`Failed to upload file: ${file.name}, error: `, err); 763 } 764 } 765 info(`All files have been uploaded.`); 766 } 767 768 769 private uploadSingleFile = async (file: File | null): Promise<void> => { 770 if (file) { 771 let writeSize = 0; 772 let wsInstance = WebSocketManager.getInstance(); 773 const fileName = file.name; 774 let bufferIndex = 0; 775 776 // 定义一个 ACK 回调函数的等待机制 777 const waitForAck = (): Promise<void> => { 778 return new Promise<void>((resolve, reject) => { 779 wsInstance!.registerMessageListener(TypeConstants.DISASSEMBLY_TYPE, onAckReceived, () => { }, true); 780 // 定义超时定时器 781 const timeout = setTimeout(() => { 782 // 超时后注销回调并拒绝 Promise 783 wsInstance!.unregisterCallback(TypeConstants.DISASSEMBLY_TYPE, onAckReceived); 784 reject(new Error('等待 ACK 超时:文件 ${fileName},索引 ${bufferIndex})')); 785 }, 10000); 786 function onAckReceived(cmd: number, result: Uint8Array): void { 787 const decoder = new TextDecoder(); 788 const jsonString = decoder.decode(result); 789 let jsonRes = JSON.parse(jsonString); 790 if (cmd === Constants.DISASSEMBLY_SAVE_BACK_CMD) { 791 if (jsonRes.fileName === fileName && jsonRes.bufferIndex === bufferIndex) { 792 wsInstance!.unregisterCallback(TypeConstants.DISASSEMBLY_TYPE, onAckReceived); 793 clearTimeout(timeout); 794 if (jsonRes.resultCode === 0) { 795 bufferIndex++; 796 // 当收到对应分片的 ACK 时,resolve Promise,继续上传下一个分片 797 resolve(); 798 } else { 799 // 上传失败,拒绝 Promise 并返回 800 reject(new Error(`Upload failed for file: ${fileName}, index: ${jsonRes.bufferIndex})`)); 801 } 802 } 803 } 804 } 805 }); 806 }; 807 808 while (writeSize < file.size) { 809 let sliceLen = Math.min(file.size - writeSize, this.REQ_BUF_SIZE); 810 let blob: Blob | null = file.slice(writeSize, writeSize + sliceLen); 811 let buffer: ArrayBuffer | null = await blob.arrayBuffer(); 812 let data: Uint8Array | null = new Uint8Array(buffer); 813 const dataObject = { 814 file_name: fileName, 815 buffer_index: bufferIndex, 816 buffer_size: sliceLen, 817 total_size: file.size, 818 is_last: writeSize + sliceLen >= file.size 819 }; 820 const dataString = JSON.stringify(dataObject); 821 const jsonStr = `${dataString.length}|${dataString}`; 822 const textEncoder = new TextEncoder(); 823 const jsonData = textEncoder.encode(jsonStr); 824 let mergeData: Uint8Array = new Uint8Array(jsonData.length + data.length); 825 mergeData.set(jsonData); 826 mergeData.set(data, jsonData.length); 827 wsInstance!.sendMessage(TypeConstants.DISASSEMBLY_TYPE, Constants.DISASSEMBLY_SAVE_CMD, mergeData); 828 writeSize += sliceLen; 829 // 等待服务器端确认当前分片的 ACK 830 await waitForAck(); 831 data = null; 832 buffer = null; 833 blob = null; 834 } 835 } 836 }; 837 838 private exportClickEvent(): void { 839 this.exportBt!.onclick = (): void => { 840 let currentTab = this.getTabpaneByKey(this.litTabs?.activekey!); 841 if (currentTab) { 842 let table1 = Array.from( 843 (currentTab.firstChild as BaseElement).shadowRoot?.querySelectorAll<LitPageTable>('lit-page-table') || [] 844 ); 845 let table2 = Array.from( 846 (currentTab.firstChild as BaseElement).shadowRoot?.querySelectorAll<LitTable>('lit-table') || [] 847 ); 848 let componentTopTable = undefined; 849 if ( 850 (currentTab.firstChild as BaseElement).shadowRoot?.querySelector('#tb-counter') && 851 ((currentTab.firstChild as BaseElement).shadowRoot?.querySelector('#tb-counter')?.firstChild as BaseElement) 852 ) { 853 componentTopTable = ((currentTab.firstChild as BaseElement).shadowRoot?.querySelector('#tb-counter') 854 ?.firstChild as BaseElement)!.shadowRoot?.querySelectorAll<LitTable>('lit-table'); 855 } 856 857 let table3 = Array.from(componentTopTable || []); 858 let tables = [...table1, ...table2, ...table3]; 859 860 for (let table of tables) { 861 if (!table.hasAttribute('hideDownload')) { 862 table.exportData(); 863 } 864 } 865 } 866 }; 867 } 868 869 getTabpaneByKey(key: string): LitTabpane | undefined { 870 let tabs = Array.from(this.shadowRoot?.querySelectorAll<LitTabpane>('#tabs lit-tabpane').values() || []); 871 return tabs.find((it) => it.key === key); 872 } 873 874 initHtml(): string { 875 return ` 876 <style> 877 :host([mode='hidden']){ 878 display: none; 879 } 880 :host{ 881 display: block; 882 background-color: rebeccapurple; 883 } 884 .tabHeight{ 885 height: 30vh; 886 background-color: var(--dark-background,#FFFFFF); 887 } 888 #check-popover[visible="true"] #check-des{ 889 color: #0A59F7; 890 } 891 .popover{ 892 color: var(--dark-color1,#4b5766); 893 justify-content: center; 894 align-items: center; 895 margin-right: 10px; 896 z-index: 2; 897 } 898 .option { 899 display: flex; 900 margin-right: 10px; 901 cursor: pointer; 902 } 903 </style> 904 <div id="vessel" style="border-top: 1px solid var(--dark-border1,#D5D5D5);"> 905 <lit-tabs id="tabs" position="top-left" activekey="1" mode="card" > 906 <div class="option" slot="options"> 907 <lit-popover placement="bottom" class="popover" haveRadio="true" trigger="click" id="options"> 908 <div slot="content"> 909 <lit-tree id="optionsSettingTree" checkable="true"></lit-tree> 910 </div> 911 <lit-icon name="setting" size="21" id="setting"></lit-icon> 912 </lit-popover> 913 </div> 914 <div slot="right" style="margin: 0 10px; color: var(--dark-icon,#606060);display: flex;align-items: center;"> 915 <lit-popover placement="bottomRight" class="popover" haveRadio="true" trigger="click" id="select-process"> 916 <div slot="content"> 917 <lit-tree id="processTree" checkable="true"></lit-tree> 918 </div> 919 <lit-icon name="setting" size="20" id="setting"></lit-icon> 920 </lit-popover> 921 <div title="So Symbolization" id="import_div" style="width: 20px;height: 20px;display: flex;flex-direction: row;margin-right: 10px"> 922 <input id="import-file" style="display: none;pointer-events: none" type="file" webkitdirectory> 923 <label style="width: 20px;height: 20px;cursor: pointer;" for="import-file"> 924 <lit-icon id="import-btn" name="so-symbol" style="pointer-events: none" size="20"> 925 </lit-icon> 926 </label> 927 </div> 928 <div title="Import SO" id="symbol_div" style="width: 20px;height: 20px;display: flex;flex-direction: row;margin-right: 10px"> 929 <input id="so-symbolization" style="display: none;pointer-events: none" type="file" webkitdirectory> 930 <label style="width: 20px;height: 20px;cursor: pointer;" for="so-symbolization"> 931 <lit-icon id="import-btn" name="copy-csv" style="pointer-events: none" size="20"> 932 </lit-icon> 933 </label> 934 </div> 935 <lit-icon title="Download Table" id="export-btn" name="import-so" style="font-weight: bold;cursor: pointer;margin-right: 10px" size="20"> 936 </lit-icon> 937 <lit-icon title="Maximize Tab" id="max-btn" name="vertical-align-top" style="font-weight: bold;cursor: pointer;margin-right: 10px" size="20"> 938 </lit-icon> 939 <lit-icon title="Minimize Tab" id="min-btn" name="down" style="font-weight: bold;cursor: pointer;" size="20"> 940 </lit-icon> 941 </div> 942 </lit-tabs> 943 </div>`; 944 } 945 displayCurrent = (data: SlicesTime): void => 946 this.displayTab<TabPaneCurrent>('tabpane-current').setCurrentSlicesTime(data); 947 displayThreadData = ( 948 data: ThreadStruct, 949 scrollCallback: ((e: ThreadStruct) => void) | undefined, 950 scrollWakeUp: (d: unknown) => void | undefined, 951 scrollPrio: (d: unknown) => void | undefined, 952 callback?: (data: Array<unknown>, str: string) => void 953 ): Promise<void> => 954 this.displayTab<TabPaneCurrentSelection>('current-selection').setThreadData( 955 data, 956 // @ts-ignore 957 scrollCallback, 958 scrollWakeUp, 959 scrollPrio, 960 callback 961 ); 962 963 displaySysCallData = (data: ThreadSysCallStruct) => 964 this.displayTab<TabPaneCurrentSelection>('current-selection').setSysCallData(data); 965 displayMemData = (data: ProcessMemStruct): void => 966 this.displayTab<TabPaneCurrentSelection>('current-selection').setMemData(data); 967 displayHangData = (data: HangStruct, sp: SpSystemTrace, scrollCallback: Function): Promise<void> => 968 this.displayTab<TabPaneCurrentSelection>('current-selection').setHangData(data, sp, scrollCallback); 969 displayClockData = (data: ClockStruct): Promise<void> => 970 this.displayTab<TabPaneCurrentSelection>('current-selection').setClockData(data); 971 displayDmaFenceData = ( 972 data: DmaFenceStruct, 973 rowData: unknown 974 ): void => //展示tab页内容 975 // @ts-ignore 976 this.displayTab<TabPaneCurrentSelection>('current-selection').setDmaFenceData(data, rowData); 977 displayXpowerData = (data: XpowerStruct): Promise<void> => 978 this.displayTab<TabPaneCurrentSelection>('current-selection').setXpowerData(data); 979 displayXpowerDisplayData = (data: XpowerAppDetailStruct): Promise<void> => 980 this.displayTab<TabPaneCurrentSelection>('current-selection').setXpowerDisplayData(data); 981 displayXpowerWifiPacketsData = (data: XpowerWifiStruct): Promise<void> => 982 this.displayTab<TabPaneCurrentSelection>('current-selection').setXpowerWifiPacketsData(data); 983 displayXpowerBytesWifiData = (data: XpowerWifiStruct): Promise<void> => 984 this.displayTab<TabPaneCurrentSelection>('current-selection').setXpowerWifiBytesData(data); 985 displayXpowerStatisticData = (data: XpowerStatisticStruct): void => 986 this.displayTab<TabPaneXpowerStatisticCurrentData>( 987 'box-xpower-statistic-current-data' 988 ).setXpowerStatisticCurrentData(data); 989 displayXpowerThreadInfoData = (dataList: Array<XpowerThreadInfoStruct>): void => { 990 this.displayTab<TabPaneXpowerThreadInfoSelection>('box-xpower-thread-info-selection').setThreadInfoData(dataList); 991 }; 992 displayXpowerGpuFreqData = (dataList: Array<XpowerGpuFreqStruct>): void => { 993 this.displayTab<TabPaneXpowerGpuFreqSelection>('box-xpower-gpu-freq-selection').setGpuFreqData(dataList); 994 }; 995 displayXpowerTreadCountData = (data: XpowerThreadCountStruct): Promise<void> => 996 this.displayTab<TabPaneCurrentSelection>('current-selection').setXpowerTreadCountData(data); 997 displayXpowerGpuFreqCountData = (data: XpowerGpuFreqCountStruct): Promise<void> => 998 this.displayTab<TabPaneCurrentSelection>('current-selection').setXpowerGpuFreqCountData(data); 999 displayPerfToolsData = (data: PerfToolStruct): void => 1000 this.displayTab<TabPaneCurrentSelection>('current-selection').setPerfToolsData(data); 1001 displayIrqData = (data: IrqStruct): void => 1002 this.displayTab<TabPaneCurrentSelection>('current-selection').setIrqData(data); 1003 displayStartupData = (data: AppStartupStruct, scrollCallback: Function, rowData: unknown): void => 1004 this.displayTab<TabPaneCurrentSelection>('current-selection').setStartupData(data, scrollCallback, rowData); 1005 displayAllStartupData = (data: AllAppStartupStruct, scrollCallback: Function): void => 1006 this.displayTab<TabPaneCurrentSelection>('current-selection').setAllStartupData(data, scrollCallback); 1007 displayStaticInitData = (data: SoStruct, scrollCallback: Function): void => 1008 this.displayTab<TabPaneCurrentSelection>('current-selection').setStaticInitData(data, scrollCallback); 1009 1010 displayNativeHookData = (data: HeapStruct, rowType: string, ipid: number): void => { 1011 let val = new SelectionParam(); 1012 val.nativeMemoryStatistic.push(rowType); 1013 val.nativeMemoryCurrentIPid = ipid; 1014 val.nativeMemory = []; 1015 val.leftNs = data.startTime! + data.dur!; 1016 val.rightNs = data.startTime! + data.dur! + 1; 1017 this.selection = val; 1018 this.displayTab<TabPaneNMStatisticAnalysis>('box-native-statistic-analysis', 'box-native-calltree').data = val; 1019 this.showUploadSoBt(val); 1020 this.showSwitchProcessBt(val); 1021 }; 1022 1023 displayGpuSelectedData = (type: string, startTs: number, dataList: Array<SnapshotStruct>): void => { 1024 this.displayTab<TabPaneGpuClickSelectComparison>('gpu-click-select-comparison').getGpuClickDataByDB( 1025 type, 1026 startTs, 1027 dataList 1028 ); 1029 let dataObject = { type: type, startTs: startTs }; 1030 this.displayTab<TabPaneGpuClickSelect>('gpu-click-select', 'gpu-click-select-comparison').gpuClickData(dataObject); 1031 }; 1032 1033 displayFuncData = ( 1034 names: string[], 1035 threadName: string, 1036 data: FuncStruct, 1037 scrollCallback: Function, 1038 callback?: (data: Array<unknown>, str: string, binderTid: number) => void, 1039 distributedCallback?: (dataList: FuncStruct[]) => void 1040 ): Promise<void> => 1041 this.displayTab<TabPaneCurrentSelection>(...names).setFunctionData( 1042 data, 1043 threadName, 1044 scrollCallback, 1045 callback, 1046 distributedCallback 1047 ); 1048 displayCpuData = ( 1049 data: CpuStruct, 1050 callback: ((data: WakeupBean | null) => void) | undefined = undefined, 1051 scrollCallback?: (data: CpuStruct) => void 1052 ): Promise<void> => 1053 this.displayTab<TabPaneCurrentSelection>('current-selection').setCpuData(data, callback, scrollCallback); 1054 displayJankData = ( 1055 data: JankStruct, 1056 callback: ((data: Array<unknown>) => void) | undefined = undefined, 1057 scrollCallback: ((e: JankStruct) => void) | undefined 1058 // @ts-ignore 1059 ): void => this.displayTab<TabPaneCurrentSelection>('current-selection').setJankData(data, callback, scrollCallback); 1060 displayShmData = (data: SnapshotStruct, dataList: Array<SnapshotStruct>): void => { 1061 this.displayTab<TabPaneVmTrackerShmComparison>('box-vmtracker-shm-comparison').setShmData(data, dataList); 1062 this.displayTab<TabPaneVmTrackerShmSelection>( 1063 'box-vmtracker-shm-selection', 1064 'box-vmtracker-shm-comparison' 1065 ).setShmData(data, dataList); 1066 }; 1067 displaySmapsData = (data: SnapshotStruct, dataList: Array<SnapshotStruct>): void => { 1068 let val = new SelectionParam(); 1069 val.smapsType = []; 1070 val.leftNs = data.startNs; 1071 this.selection = val; 1072 val.smapsType = []; 1073 this.displayTab<TabPaneSmapsComparison>('box-smaps-comparison').setData(val, dataList); 1074 this.displayTab<TabPaneSmapsStatistics>( 1075 'box-smaps-statistics', 1076 'box-smaps-sample', 1077 'box-smaps-comparison', 1078 'box-smaps-record' 1079 ).data = val; 1080 }; 1081 displaySnapshotData = ( 1082 data: HeapSnapshotStruct, 1083 dataListCache: Array<HeapSnapshotStruct>, 1084 scrollCallback?: (data: HeapSnapshotStruct, dataListCache: Array<HeapSnapshotStruct>) => void 1085 ): void => { 1086 if (dataListCache.length > 1) { 1087 this.displayTab<TabPaneSummary>('box-heap-summary', 'box-heap-comparison').setSnapshotData( 1088 data, 1089 dataListCache, 1090 scrollCallback 1091 ); 1092 let nav = this.shadowRoot!.querySelector('#tabs')!.shadowRoot!.querySelector( 1093 '#nav > #nav-comparison' 1094 ) as HTMLDivElement; 1095 let tabPaneComparison = this.shadowRoot!.querySelector( 1096 '#box-heap-comparison > tabpane-comparison' 1097 ) as TabPaneComparison; 1098 nav!.onclick = (): void => { 1099 tabPaneComparison.initComparison(data, dataListCache); 1100 }; 1101 } else { 1102 this.displayTab<TabPaneSummary>('box-heap-summary').setSnapshotData(data, dataListCache, scrollCallback); 1103 } 1104 }; 1105 displayFlagData = (flagObj: Flag): void => this.displayTab<TabPaneFlag>('box-flag').setCurrentFlag(flagObj); 1106 displayFreqData = (): CpuFreqStruct | undefined => 1107 (this.displayTab<TabPaneCurrentSelection>('box-freq').data = CpuFreqStruct.selectCpuFreqStruct); 1108 displayCpuStateData = (): CpuStateStruct | undefined => 1109 (this.displayTab<TabPaneCurrentSelection>('cpu-state-click').data = CpuStateStruct.selectStateStruct); 1110 displayFreqLimitData = (): CpuFreqLimitsStruct | undefined => 1111 (this.displayTab<TabPaneCurrentSelection>('box-freq-limit').data = CpuFreqLimitsStruct.selectCpuFreqLimitsStruct); 1112 1113 displayFrameAnimationData = (data: FrameAnimationStruct, scrollCallback: Function): Promise<void> => 1114 this.displayTab<TabPaneCurrentSelection>('current-selection').setFrameAnimationData(data, scrollCallback); 1115 displayFrameDynamicData = (row: TraceRow<FrameDynamicStruct>, data: FrameDynamicStruct): void => 1116 this.displayTab<TabPaneFrameDynamic>('box-frame-dynamic').buildDynamicTable([data], true); 1117 displayFrameSpacingData = (data: FrameSpacingStruct): void => 1118 this.displayTab<TabFrameSpacing>('box-frames-spacing').setFrameSpacingData(data); 1119 displayJsProfilerData = (data: Array<JsCpuProfilerChartFrame>): void => { 1120 let val = new SelectionParam(); 1121 val.jsCpuProfilerData = data; 1122 this.selection = val; 1123 this.displayTab<TabPaneJsCpuStatistics>( 1124 'box-js-Profiler-statistics', 1125 'box-js-Profiler-bottom-up', 1126 'box-js-Profiler-top-down' 1127 ).data = data; 1128 }; 1129 displayPurgTotalAbilityData = (data: SnapshotStruct, dataList: Array<SnapshotStruct>): void => { 1130 data.type = 'ability'; 1131 this.displayTab<TabPanePurgTotalComparisonAbility>('box-purgeable-total-comparison-ability').totalData( 1132 data, 1133 dataList 1134 ); 1135 this.displayTab<TabPanePurgTotalSelection>( 1136 'box-purgeable-total-selection', 1137 'box-purgeable-total-comparison-ability' 1138 ).data = data; 1139 }; 1140 displayPurgPinAbilityData = (data: SnapshotStruct, dataList: Array<SnapshotStruct>): void => { 1141 data.type = 'ability'; 1142 this.displayTab<TabPanePurgPinComparisonAbility>('box-purgeable-pin-comparison-ability').totalData(data, dataList); 1143 this.displayTab<TabPanePurgPinSelection>( 1144 'box-purgeable-pin-selection', 1145 'box-purgeable-pin-comparison-ability' 1146 ).data = data; 1147 }; 1148 displayPurgTotalVMData = (data: SnapshotStruct, dataListCache: Array<SnapshotStruct>): void => { 1149 data.type = 'VM'; 1150 this.displayTab<TabPanePurgTotalComparisonVM>('box-purgeable-total-comparison-vm').totalData(data, dataListCache); 1151 this.displayTab<TabPanePurgTotalSelection>( 1152 'box-purgeable-total-selection', 1153 'box-purgeable-total-comparison-vm' 1154 ).data = data; 1155 }; 1156 displayPurgPinVMData = (data: SnapshotStruct, dataListCache: Array<SnapshotStruct>): void => { 1157 data.type = 'VM'; 1158 this.displayTab<TabPanePurgPinComparisonVM>('box-purgeable-pin-comparison-vm').totalData(data, dataListCache); 1159 this.displayTab<TabPanePurgPinSelection>('box-purgeable-pin-selection', 'box-purgeable-pin-comparison-vm').data = 1160 data; 1161 }; 1162 displayDmaAbility = (data: number, dataList: Array<SnapshotStruct>): void => { 1163 if (dataList.length > 0) { 1164 this.displayTab<TabPaneDmaAbilityComparison>('box-dma-ability-comparison').comparisonDataByDB(data, dataList); 1165 this.displayTab<TabPaneDmaSelectAbility>( 1166 'box-dma-selection-ability', 1167 'box-dma-ability-comparison' 1168 ).queryDmaClickDataByDB(data); 1169 } else { 1170 this.displayTab<TabPaneDmaSelectAbility>('box-dma-selection-ability').queryDmaClickDataByDB(data); 1171 } 1172 }; 1173 displayDmaVmTracker = (data: number, dataListCache: Array<SnapshotStruct>): void => { 1174 if (dataListCache.length > 0) { 1175 this.displayTab<TabPaneDmaVmTrackerComparison>('box-vmTracker-comparison').comparisonDataByDB( 1176 data, 1177 dataListCache 1178 ); 1179 this.displayTab<TabPaneDmaSelectVmTracker>( 1180 'box-dma-selection-vmTracker', 1181 'box-vmTracker-comparison' 1182 ).queryDmaVmTrackerClickDataByDB(data); 1183 } else { 1184 this.displayTab<TabPaneDmaSelectVmTracker>('box-dma-selection-vmTracker').queryDmaVmTrackerClickDataByDB(data); 1185 } 1186 }; 1187 displayGpuMemoryAbility = (data: number, dataList: Array<SnapshotStruct>): void => { 1188 if (dataList.length > 0) { 1189 this.displayTab<TabPaneGpuMemoryComparison>('box-gpu-memory-comparison').comparisonDataByDB(data, dataList); 1190 this.displayTab<TabPaneGpuMemorySelectAbility>( 1191 'box-gpu-memory-selection-ability', 1192 'box-gpu-memory-comparison' 1193 ).queryGpuMemoryClickDataByDB(data); 1194 } else { 1195 this.displayTab<TabPaneGpuMemorySelectAbility>('box-gpu-memory-selection-ability').data = data; 1196 } 1197 }; 1198 displayGpuMemoryVmTracker = (data: number, dataListCache: Array<SnapshotStruct>): void => { 1199 if (dataListCache.length > 0) { 1200 this.displayTab<TabPaneGpuMemoryVmTrackerComparison>('box-gpu-memory-vmTracker-comparison').comparisonDataByDB( 1201 data, 1202 dataListCache 1203 ); 1204 this.displayTab<TabPaneGpuMemorySelectVmTracker>( 1205 'box-gpu-memory-selection-vmTracker', 1206 'box-gpu-memory-vmTracker-comparison' 1207 ).queryGpuMemoryVmTrackerClickDataByDB(data); 1208 } else { 1209 this.displayTab<TabPaneGpuMemorySelectVmTracker>( 1210 'box-gpu-memory-selection-vmTracker' 1211 ).queryGpuMemoryVmTrackerClickDataByDB(data); 1212 } 1213 }; 1214 displayGpuResourceVmTracker = (data: number): void => { 1215 this.displayTab<TabPaneGpuResourceVmTracker>('box-smaps-gpu-resource').data = data; 1216 }; 1217 1218 displaySystemLogsData = (): void => { 1219 let tblHiLogPanel = this.shadowRoot?.querySelector<LitTabpane>("lit-tabpane[id='box-hilogs']"); 1220 if (tblHiLogPanel) { 1221 let tblHiLog = tblHiLogPanel.querySelector<TabPaneHiLogs>('tab-hi-log'); 1222 if (tblHiLog) { 1223 tblHiLog.initTabSheetEl(this); 1224 } 1225 } 1226 }; 1227 1228 displayHangsData = (): void => { 1229 let tblHangPanel = this.shadowRoot?.querySelector<LitTabpane>("lit-tabpane[id='box-hang']"); 1230 if (tblHangPanel) { 1231 let tblHang = tblHangPanel.querySelector<TabPaneHiLogs>('tab-hang'); 1232 if (tblHang) { 1233 tblHang.initTabSheetEl(this); 1234 } 1235 } 1236 }; 1237 1238 displaySampleData = (data: SampleStruct, reqProperty: unknown): void => { 1239 this.displayTab<TabPaneSampleInstruction>('box-sample-instruction').setSampleInstructionData(data, reqProperty); 1240 this.optionsDiv!.style.display = 'flex'; 1241 const select = 1242 this.optionsSettingTree!.getCheckdKeys().length === 0 ? ['0'] : this.optionsSettingTree!.getCheckdKeys(); 1243 this.optionsSettingTree!.treeData = [ 1244 { key: '0', title: 'instruction', checked: select[0] === '0' }, 1245 { key: '1', title: 'cycles', checked: select[0] === '1' }, 1246 ]; 1247 }; 1248 displayUserPlugin = (selectData: unknown): void => { 1249 this.displayTab<TabPaneUserPlugin>('tab-pane-userplugin').data = selectData; 1250 }; 1251 1252 displayGpuCounterData = (data: GpuCounterStruct): void => { 1253 this.displayTab<TabPaneGpuCounter>('box-gpu-counter').data = data; 1254 }; 1255 1256 displaySystemStatesData = (): void => { 1257 let dataCutPane = this.shadowRoot?.querySelector<TabPaneDataCut>('tabpane-datacut'); 1258 if (dataCutPane) { 1259 dataCutPane.initTabSheetEl(this); 1260 } 1261 let tblStatesPanel = this.shadowRoot?.querySelector<TabPaneFreqStatesDataCut>('tabpane-states-datacut'); 1262 if (tblStatesPanel) { 1263 tblStatesPanel.initTabSheetEl(this); 1264 } 1265 }; 1266 rangeSelect(selection: SelectionParam, restore = false): boolean { 1267 this.selection = selection; 1268 this.exportBt!.style.display = 'flex'; 1269 this.showUploadSoBt(selection); 1270 this.showSwitchProcessBt(selection); 1271 this.showOptionsBt(selection); // @ts-ignore 1272 Reflect.ownKeys(tabConfig) 1273 .reverse() 1274 .forEach((id) => { 1275 // @ts-ignore 1276 let element = tabConfig[id]; 1277 let pane = this.shadowRoot!.querySelector<LitTabpane>(`#${id as string}`); 1278 if (pane) { 1279 pane.hidden = !(element.require && element.require(selection)); 1280 } 1281 }); 1282 if (restore) { 1283 if (this.litTabs?.activekey) { 1284 if (this.loadSoComplete) { 1285 let analysisTabpane = this.shadowRoot!.querySelector('#box-perf-analysis') as LitTabpane; 1286 if (analysisTabpane && this.litTabs) { 1287 this.litTabs.activekey = analysisTabpane.key; 1288 } 1289 } 1290 this.loadTabPaneData(this.litTabs?.activekey); 1291 this.setMode('max'); 1292 return true; 1293 } else { 1294 this.setMode('hidden'); 1295 return false; 1296 } 1297 } else { 1298 let firstPane = this.shadowRoot!.querySelector<LitTabpane>("lit-tabpane[hidden='false']"); 1299 if (firstPane) { 1300 this.litTabs?.activeByKey(firstPane.key); 1301 this.loadTabPaneData(firstPane.key); 1302 this.setMode('max'); 1303 return true; 1304 } else { 1305 this.setMode('hidden'); 1306 return false; 1307 } 1308 } 1309 } 1310 1311 showOptionsBt(selection: SelectionParam | null | undefined): void { 1312 if (selection && selection.sampleData.length > 0) { 1313 this.optionsDiv!.style.display = 'flex'; 1314 const select = 1315 this.optionsSettingTree!.getCheckdKeys().length === 0 ? ['0'] : this.optionsSettingTree!.getCheckdKeys(); 1316 this.optionsSettingTree!.treeData = [ 1317 { key: '0', title: 'instruction', checked: select[0] === '0' }, 1318 { key: '1', title: 'cycles', checked: select[0] === '1' }, 1319 ]; 1320 } else { 1321 this.optionsDiv!.style.display = 'none'; 1322 } 1323 } 1324 1325 updateRangeSelect(ipid?: number): boolean { 1326 if ( 1327 this.selection && 1328 (this.selection.nativeMemory.length > 0 || 1329 this.selection.nativeMemoryStatistic.length > 0 || 1330 this.selection.perfSampleIds.length > 0 || 1331 this.selection.fileSystemType.length > 0 || 1332 this.selection.fsCount > 0 || 1333 this.selection.fileSysVirtualMemory || 1334 this.selection.vmCount > 0 || 1335 this.selection.diskIOLatency || 1336 this.selection.diskIOipids.length > 0) 1337 ) { 1338 let param: SelectionParam = new SelectionParam(); 1339 Object.assign(param, this.selection); 1340 if (param.nativeMemory.length > 0 || param.nativeMemoryStatistic.length > 0) { 1341 Utils.getInstance().initResponseTypeList(param); 1342 if (ipid) { 1343 Utils.getInstance().setCurrentSelectIPid(ipid); 1344 param.nativeMemoryCurrentIPid = ipid; 1345 } 1346 } 1347 param.isImportSo = true; 1348 this.rangeSelect(param, true); 1349 return true; 1350 } else { 1351 return false; 1352 } 1353 } 1354 1355 showUploadSoBt(selection: SelectionParam | null | undefined): void { 1356 if ( 1357 selection && 1358 (selection.nativeMemory.length > 0 || 1359 selection.nativeMemoryStatistic.length > 0 || 1360 selection.perfSampleIds.length > 0 || 1361 selection.fileSystemType.length > 0 || 1362 selection.fsCount > 0 || 1363 selection.fileSysVirtualMemory || 1364 selection.vmCount > 0 || 1365 selection.diskIOLatency || 1366 selection.diskIOipids.length > 0 || 1367 selection.threadIds.length > 0) 1368 ) { 1369 this.importDiv!.style.display = 'flex'; 1370 this.symbolDiv!.style.display = 'flex'; 1371 } else { 1372 this.importDiv!.style.display = 'none'; 1373 this.symbolDiv!.style.display = 'none'; 1374 } 1375 } 1376 isProcessEqual(treeData: Array<{ pid: number; ipid: number }>): boolean { 1377 if (treeData.length !== this.lastProcessSet.size) { 1378 return false; 1379 } 1380 for (let process of treeData) { 1381 if (!this.lastProcessSet.has(process.pid)) { 1382 return false; 1383 } 1384 } 1385 return true; 1386 } 1387 1388 showSwitchProcessBt(selection: SelectionParam | null | undefined): void { 1389 // 2个及以上进程再显示 1390 if (selection && selection.nativeMemoryAllProcess.length > 1) { 1391 this.switchDiv!.style.display = 'flex'; 1392 if (this.isProcessEqual(selection.nativeMemoryAllProcess)) { 1393 if (this.processTree) { 1394 for (const data of this.processTree.treeData) { 1395 if (data.key === `${selection.nativeMemoryCurrentIPid}`) { 1396 data.checked = true; 1397 } else { 1398 data.checked = false; 1399 } 1400 } 1401 //调用set重新更新界面 1402 this.processTree.treeData = this.processTree.treeData; 1403 } 1404 return; 1405 } 1406 this.lastProcessSet = new Set<number>(); 1407 const processArray: Array<TreeItemData> = []; 1408 let isFirst: boolean = true; 1409 for (let process of selection.nativeMemoryAllProcess) { 1410 const treeData: TreeItemData = { 1411 key: `${process.ipid}`, 1412 title: `Process ${process.pid}`, 1413 checked: isFirst, 1414 }; 1415 if (isFirst) { 1416 this.lastSelectIPid = process.ipid; 1417 isFirst = false; 1418 } 1419 processArray.push(treeData); 1420 this.lastProcessSet.add(process.pid); 1421 } 1422 this.processTree!.treeData = processArray; 1423 } else { 1424 this.switchDiv!.style.display = 'none'; 1425 } 1426 } 1427 1428 loadTabPaneData(key: string): void { 1429 let component: unknown = this.shadowRoot 1430 ?.querySelector<LitTabpane>(`#tabs lit-tabpane[key='${key}']`) 1431 ?.children.item(0); 1432 if (component) { 1433 // @ts-ignore 1434 component.data = this.selection; 1435 if (this.selection) { 1436 this.selection.isRowClick = false; 1437 } 1438 } 1439 } 1440 1441 setMode(mode: string): void { 1442 let delta = this.clientHeight; 1443 let show = mode === 'max' ? 1 : -1; 1444 this.setAttribute('mode', mode); 1445 if (mode === 'hidden') { 1446 this.selection = undefined; 1447 } 1448 window.publish(window.SmartEvent.UI.ShowBottomTab, { show: show, delta: delta }); 1449 } 1450 1451 tdClickHandler(e: unknown, isDependCpu?: boolean): void { 1452 // @ts-ignore 1453 this.currentPaneID = e.target.parentElement.id; 1454 //隐藏除了当前Tab页的其他Tab页 1455 this.shadowRoot!.querySelectorAll<LitTabpane>('lit-tabpane').forEach((it): boolean => 1456 it.id !== this.currentPaneID ? (it.hidden = true) : (it.hidden = false) 1457 ); //todo:看能不能优化 1458 let pane = this.getPaneByID('box-cpu-child'); //通过Id找到需要展示的Tab页 1459 pane.closeable = true; //关闭的ican显示 1460 pane.hidden = false; 1461 this.litTabs!.activeByKey(pane.key); //显示key值对应的Tab页 1462 // @ts-ignore 1463 pane.tab = e.detail.tabTitle ? e.detail.tabTitle : Utils.transferPTSTitle(e.detail.title); //设置Tab页标题,有的标题可直接用,有的标题需在此转换成需要展示的字符串 1464 let param = new BoxJumpParam(); 1465 param.traceId = this.selection!.traceId; 1466 param.leftNs = this.selection!.leftNs; 1467 param.rightNs = this.selection!.rightNs; 1468 param.cpus = isDependCpu ? this.selection!.cpus : []; 1469 // @ts-ignore 1470 param.state = e.detail.summary ? '' : e.detail.state; 1471 // @ts-ignore 1472 param.processId = e.detail.summary ? this.selection.processIds : e.detail.pid; 1473 // @ts-ignore 1474 param.threadId = e.detail.summary ? this.selection.threadIds : e.detail.tid; 1475 param.isJumpPage = true; // @ts-ignore 1476 param.currentId = e.target.parentElement.id; //根据父Tab页的标题,确认子Tab页的dur是否需要处理 1477 (pane.children.item(0) as TabPaneBoxChild).data = param; 1478 } 1479 1480 tdSysCallClickHandler(e: unknown): void { 1481 // @ts-ignore 1482 this.currentPaneID = e.target.parentElement.id; 1483 //隐藏除了当前Tab页的其他Tab页 1484 this.shadowRoot!.querySelectorAll<LitTabpane>('lit-tabpane').forEach((it): boolean => 1485 it.id !== this.currentPaneID ? (it.hidden = true) : (it.hidden = false) 1486 ); //todo:看能不能优化 1487 let pane = this.getPaneByID('box-thread-syscall-child'); //通过Id找到需要展示的Tab页 1488 pane.closeable = true; //关闭的ican显示 1489 pane.hidden = false; 1490 this.litTabs!.activeByKey(pane.key); //显示key值对应的Tab页 1491 // @ts-ignore 1492 pane.tab = e.detail.name; //设置Tab页标题,有的标题可直接用,有的标题需在此转换成需要展示的字符串 1493 let param = new SysCallBoxJumpParam(); 1494 param.traceId = this.selection!.traceId; 1495 param.leftNs = this.selection!.leftNs; 1496 param.rightNs = this.selection!.rightNs; 1497 // @ts-ignore 1498 const level = e.detail.level; 1499 if (level === 'Process') { 1500 // @ts-ignore 1501 param.processId = [e.detail.id]; 1502 } else if (level === 'Thread'){ 1503 // @ts-ignore 1504 param.processId = [e.detail.parentId]; 1505 // @ts-ignore 1506 param.threadId = [e.detail.id]; 1507 } else { 1508 // @ts-ignore 1509 param.threadId = [e.detail.parentId]; 1510 // @ts-ignore 1511 param.sysCallId = e.detail.id; 1512 } 1513 param.isJumpPage = true; // @ts-ignore 1514 (pane.children.item(0) as TabPaneSysCallChild).data = param; 1515 } 1516 1517 tdPerfSampleClickHandler(e: unknown): void { 1518 // @ts-ignore 1519 this.currentPaneID = e.target.parentElement.id; 1520 //隐藏除了当前Tab页的其他Tab页 1521 this.shadowRoot!.querySelectorAll<LitTabpane>('lit-tabpane').forEach((it): boolean => 1522 it.id !== this.currentPaneID ? (it.hidden = true) : (it.hidden = false) 1523 ); //todo:看能不能优化 1524 let pane = this.getPaneByID('box-perf-sample-child'); //通过Id找到需要展示的Tab页 1525 pane.closeable = true; //关闭的ican显示 1526 pane.hidden = false; 1527 this.litTabs!.activeByKey(pane.key); //显示key值对应的Tab页 1528 // @ts-ignore 1529 pane.tab = e.detail.symbol; //设置Tab页标题,有的标题可直接用,有的标题需在此转换成需要展示的字符串 1530 let param = new PerfSampleBoxJumpParam(); 1531 param.traceId = this.selection!.traceId; 1532 param.leftNs = this.selection!.leftNs; 1533 param.rightNs = this.selection!.rightNs; 1534 //@ts-ignore 1535 param.pid = e.detail.pid; 1536 //@ts-ignore 1537 param.tid = e.detail.tid; 1538 //@ts-ignore 1539 param.count = e.detail.dur || 0; 1540 //@ts-ignore 1541 param.tsArr = e.detail.tsArray || []; 1542 param.isJumpPage = true; 1543 (pane.children.item(0) as TabPanePerfSampleChild).data = param; 1544 } 1545 1546 //Slice Tab点击Occurrences列下的td进行跳转 1547 tdSliceClickHandler(e: unknown): void { 1548 // @ts-ignore 1549 this.currentPaneID = e.target.parentElement.id; 1550 //隐藏除了当前Tab页的其他Tab页 1551 this.shadowRoot!.querySelectorAll<LitTabpane>('lit-tabpane').forEach((it): boolean => 1552 it.id !== this.currentPaneID ? (it.hidden = true) : (it.hidden = false) 1553 ); 1554 let pane = this.getPaneByID('box-slice-child'); //通过Id找到需要展示的Tab页 1555 pane.closeable = true; 1556 pane.hidden = false; 1557 this.litTabs!.activeByKey(pane.key); //显示key值(sheetconfig里面对应的index是一个数字)对应的Tab页 1558 // @ts-ignore 1559 pane.tab = e.detail.tabTitle; //设置Tab页标题 1560 let param = new SliceBoxJumpParam(); 1561 param.traceId = this.selection!.traceId; 1562 param.leftNs = this.selection!.leftNs; 1563 param.rightNs = this.selection!.rightNs; 1564 param.processId = this.selection!.processIds; 1565 param.threadId = this.selection!.funTids; //@ts-ignore2 1566 param.name = e.detail.allName ? e.detail.allName : [e.detail.name]; //@ts-ignore2 1567 param.isJumpPage = true; // @ts-ignore 1568 param.isSummary = e.detail.allName ? true : false; 1569 (pane.children.item(0) as TabPaneSliceChild).data = { param: param, selection: this.selection }; 1570 } 1571 1572 clearMemory(): void { 1573 let allTabs = Array.from(this.shadowRoot?.querySelectorAll<LitTabpane>('#tabs lit-tabpane').values() || []); 1574 allTabs.forEach((tab) => { 1575 if (tab) { 1576 let tables = Array.from( 1577 (tab.firstChild as BaseElement).shadowRoot?.querySelectorAll<LitTable>('lit-table') || [] 1578 ); 1579 for (let table of tables) { 1580 table.recycleDataSource = []; 1581 } 1582 } 1583 }); 1584 } 1585} 1586