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