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 sp 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 { JankStruct } from '../database/ui-worker/ProcedureWorkerJank';
17import { SpSystemTrace } from './SpSystemTrace';
18import { TraceRow } from './trace/base/TraceRow';
19import { LineType, PairPoint, ns2xByTimeShaft } from '../database/ui-worker/ProcedureWorkerCommon';
20import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames';
21import { FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc';
22import { queryBySelectExecute } from '../database/sql/ProcessThread.sql';
23import { queryTaskPoolOtherRelationData, queryTaskPoolRelationData } from '../database/sql/Func.sql';
24import { queryBySelectAllocationOrReturn } from '../database/sql/SqlLite.sql';
25import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread';
26import { Utils } from './trace/base/Utils';
27import { TraceMode } from '../SpApplicationPublicFunc';
28import { BaseStruct } from '../bean/BaseStruct';
29import { getTimeString } from './trace/sheet/TabPaneCurrentSelection';
30
31//@ts-ignore
32function collectionHasJank(jankRow: unknown, collectList: TraceRow<unknown>[]): boolean {
33  for (let item of collectList!) {
34    //@ts-ignore
35    if (item.rowId === jankRow.rowId && item.rowType === jankRow.rowType) {
36      return false;
37    }
38  }
39  return true;
40}
41
42function setPoint(
43  x: number,
44  y: number,
45  offsetY: number,
46  ns: number,
47  rowEL: unknown,
48  isRight: boolean,
49  business: string
50): PairPoint {
51  return {
52    x: x,
53    y: y,
54    offsetY: offsetY,
55    ns: ns,
56    rowEL: rowEL!,
57    isRight: isRight,
58    business: business,
59  } as PairPoint;
60}
61
62function addPointHandle(
63  sp: SpSystemTrace,
64  sourceData: FuncStruct,
65  sourceThreadRow: TraceRow<BaseStruct>,
66  targetData: FuncStruct,
67  targetThreadRow: TraceRow<BaseStruct>,
68  lineType?: string
69): void {
70  let sourceParentRow: TraceRow<BaseStruct> | null | undefined;
71  let targetParentRow: TraceRow<BaseStruct> | null | undefined;
72  if (Utils.currentTraceMode === TraceMode.DISTRIBUTED) {
73    sourceParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>(
74      `trace-row[row-id='${sourceData.pid}-${sourceData.traceId}'][row-type='process'][folder]`
75    );
76    targetParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>(
77      `trace-row[row-id='${targetData.pid}-${targetData.traceId}'][row-type='process'][folder]`
78    );
79  } else {
80    sourceParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>(
81      `trace-row[row-id='${sourceData.pid}'][row-type='process'][folder]`
82    );
83    targetParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>(
84      `trace-row[row-id='${targetData.pid}'][row-type='process'][folder]`
85    );
86  }
87  let [startY, startOffSetY, startRowEl, isThreadRow] =
88    getPointModel(sp, sourceThreadRow, sourceParentRow, sourceData, 0.9);
89  let [endY, endOffSetY, endRowEl] =
90    getPointModel(sp, targetThreadRow, targetParentRow, targetData, 0.1);
91  let startX = Math.floor(ns2xByTimeShaft(sourceData.ts || sourceData.startTs || 0, sp.timerShaftEL!));
92  let endX = Math.floor(ns2xByTimeShaft(targetData.ts! || targetData.startTs!, sp.timerShaftEL!));
93  const startPoint = setPoint(startX, startY, startOffSetY, sourceData.ts || sourceData.startTs || 0, startRowEl, true, 'distributed');
94  const endPoint = setPoint(endX, endY, endOffSetY, targetData.ts! || targetData.startTs!, endRowEl, true, 'distributed');
95  startPoint.rangeTime = `${getTimeString((targetData.ts || targetData.startTs! || 0) - (sourceData.ts || sourceData.startTs || 0))}`;
96  if (startPoint && endPoint) {
97    startPoint.lineType = endPoint.lineType = LineType.brokenLine;
98    startPoint.lineColor = endPoint.lineColor = '#ff0000';
99    sp.addPointPair(startPoint, endPoint, lineType);
100  }
101}
102
103function getPointModel(
104  sp: SpSystemTrace,
105  threadRow: TraceRow<BaseStruct> | null | undefined,
106  parentRow: TraceRow<BaseStruct> | null | undefined,
107  dataStruct: FuncStruct,
108  pointYHeight: number,
109): [number, number, TraceRow<BaseStruct>, boolean] {
110  let pointY: number = 0;
111  let isThreadRow = false;
112  let pointRowEl: TraceRow<BaseStruct> | null | undefined;
113  let pointOffSetY: number = 0;
114  if (threadRow) {
115    pointY = threadRow?.translateY + 20 * (dataStruct.depth! + pointYHeight);
116    pointRowEl = threadRow;
117    pointOffSetY = 20 * (dataStruct.depth! + pointYHeight);
118    isThreadRow = true;
119  } else if (parentRow) {
120    if (!parentRow.expansion) {
121      pointY = parentRow?.translateY! + 4 * (dataStruct.depth! + 0.5);
122      pointRowEl = parentRow!;
123      pointOffSetY = 4 * (dataStruct.depth! + 0.5);
124    }
125  } else {
126    pointRowEl = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>(
127      `trace-row[row-id='trace-${dataStruct.traceId}'][row-type='trace-${dataStruct.traceId}'][folder]`
128    );
129    pointY = pointRowEl?.translateY! + 4 * (dataStruct.depth! + 0.5);
130    pointOffSetY = 4 * (dataStruct.depth! + 0.5);
131  }
132  return [pointY, pointOffSetY, pointRowEl!, isThreadRow];
133}
134
135function selectJankApp(
136  endParentRow: unknown,
137  sp: SpSystemTrace,
138  data: unknown,
139  startRow: unknown,
140  selectJankStruct: JankStruct,
141  endRowStruct: unknown
142): void {
143  let collectList = sp.favoriteChartListEL!.getAllCollectRows();
144  //@ts-ignore
145  let findJankEntry = endRowStruct!.dataListCache!.find(
146    //@ts-ignore
147    (dat: unknown) => `${dat.name}` === `${data.name}` && `${dat.pid}` === `${data.pid}`
148  );
149  let tts =
150    findJankEntry.frameType === 'frameTime' ? selectJankStruct.ts! : selectJankStruct.ts! + selectJankStruct.dur!;
151  let startParentRow: unknown;
152  // startRow为子泳道,子泳道不存在,使用父泳道
153  if (startRow) {
154    startParentRow = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
155      //@ts-ignore
156      `trace-row[row-type='process'][row-id='${startRow.rowParentId}'][folder]`
157    );
158  } else {
159    startRow = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
160      `trace-row[row-type='process'][row-id='${selectJankStruct?.pid}'][folder]`
161    );
162  }
163  //@ts-ignore
164  let endY = endRowStruct!.translateY! + 20 * (findJankEntry!.depth! + 0.5);
165  let endRowEl = endRowStruct;
166  let endOffSetY = 20 * (findJankEntry!.depth! + 0.5);
167  let expansionFlag = collectionHasJank(endRowStruct, collectList);
168  //@ts-ignore
169  if (!endParentRow.expansion && expansionFlag) {
170    //@ts-ignore
171    endY = endParentRow!.translateY! + 10 * (findJankEntry!.depth! + 0.5);
172    endRowEl = endParentRow;
173    endOffSetY = 10 * (findJankEntry!.depth! + 0.5);
174  }
175  //@ts-ignore
176  let startY = startRow!.translateY! + 20 * (selectJankStruct!.depth! + 0.5);
177  let startRowEl = startRow;
178  let startOffSetY = 20 * (selectJankStruct!.depth! + 0.5);
179  expansionFlag = collectionHasJank(startRow, collectList);
180  //@ts-ignore
181  if (startParentRow && !startParentRow.expansion && expansionFlag) {
182    //@ts-ignore
183    startY = startParentRow!.translateY! + 10 * (selectJankStruct!.depth! + 0.5);
184    startRowEl = startParentRow;
185    startOffSetY = 10 * (selectJankStruct!.depth! + 0.5);
186  }
187  let startX = ns2xByTimeShaft(tts, sp.timerShaftEL!);
188  let endX = ns2xByTimeShaft(findJankEntry.ts!, sp.timerShaftEL!);
189  const startPoint = setPoint(startX, startY, startOffSetY, tts, startRowEl, selectJankStruct.ts === tts, 'janks');
190  const endPoint = setPoint(endX, endY, endOffSetY, findJankEntry.ts!, endRowEl, true, 'janks');
191  //@ts-ignore
192  sp.addPointPair(startPoint, endPoint);
193}
194
195function findJankApp(
196  endParentRow: unknown,
197  sp: SpSystemTrace,
198  data: unknown,
199  startRow: unknown,
200  selectJankStruct: JankStruct,
201  endRowStruct: unknown
202): void {
203  let collectList = sp.favoriteChartListEL!.getAllCollectRows();
204  //@ts-ignore
205  let findJankEntry = endRowStruct!.dataListCache!.find(
206    //@ts-ignore
207    (dat: unknown) => dat.name === data.name && dat.pid === data.pid
208  );
209  let tts = selectJankStruct.frameType === 'frameTime' ? findJankEntry.ts : findJankEntry.ts! + findJankEntry.dur!;
210  //@ts-ignore
211  let endY = endRowStruct!.translateY! + 20 * (findJankEntry!.depth! + 0.5);
212  let endRowEl = endRowStruct;
213  let endOffSetY = 20 * (findJankEntry!.depth! + 0.5);
214  let expansionFlag = collectionHasJank(endRowStruct, collectList);
215  //@ts-ignore
216  if (!endParentRow.expansion && expansionFlag) {
217    //@ts-ignore
218    endY = endParentRow!.translateY! + 10 * (findJankEntry!.depth! + 0.5);
219    endRowEl = endParentRow;
220    endOffSetY = 10 * (findJankEntry!.depth! + 0.5);
221  }
222  //@ts-ignore
223  let startY = startRow!.translateY! + 20 * (selectJankStruct!.depth! + 0.5);
224  let startRowEl = startRow;
225  expansionFlag = collectionHasJank(startRow, collectList);
226  let startOffsetY = 20 * (selectJankStruct!.depth! + 0.5);
227  let startParentRow = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
228    //@ts-ignore
229    `trace-row[row-type='process'][row-id='${startRow.rowParentId}'][folder]`
230  );
231  if (startParentRow && !startParentRow.expansion && expansionFlag) {
232    startY = startParentRow!.translateY! + 10 * (selectJankStruct!.depth! + 0.5);
233    startRowEl = startParentRow;
234    startOffsetY = 10 * (selectJankStruct!.depth! + 0.5);
235  }
236  let startX = ns2xByTimeShaft(selectJankStruct.ts!, sp.timerShaftEL!);
237  let endX = ns2xByTimeShaft(tts, sp.timerShaftEL!);
238  const startPoint = setPoint(startX, startY, startOffsetY, selectJankStruct.ts!, startRowEl, true, 'janks');
239  const endPoint = setPoint(endX, endY, endOffSetY, tts, endRowEl, selectJankStruct.ts === tts, 'janks');
240  //@ts-ignore
241  sp.addPointPair(startPoint, endPoint);
242}
243
244function addPointLink(
245  endParentRow: unknown,
246  sp: SpSystemTrace,
247  data: unknown,
248  startRow: unknown,
249  selectJankStruct: JankStruct,
250  endRowStruct: unknown
251): void {
252  //@ts-ignore
253  let findJankEntry = endRowStruct!.dataListCache!.find(
254    //@ts-ignore
255    (dat: unknown) => dat.name === data.name && dat.pid === data.pid
256  );
257  //连线规则:frametimeline的头----app的头,app的尾----renderservice的头
258  let tts: number = 0;
259  if (findJankEntry) {
260    if (selectJankStruct.frameType === 'app') {
261      selectJankApp(endParentRow, sp, data, startRow, selectJankStruct, endRowStruct);
262    }
263    if (findJankEntry.frameType === 'app') {
264      //@ts-ignore
265      findJankApp(endParentRow, sp, data, startRow, selectJankStruct, endRowStruct);
266    }
267    //@ts-ignore
268    if (data.children.length >= 1) {
269      let endP;
270      //@ts-ignore
271      if (data.children[0].frameType === 'frameTime') {
272        //@ts-ignore
273        endP = sp.shadowRoot?.querySelector<TraceRow<unknown>>(`trace-row[row-type='janks'][row-id='frameTime']`);
274      } else {
275        //@ts-ignore
276        endP = sp.shadowRoot?.querySelector<TraceRow<unknown>>(
277          //@ts-ignore
278          `trace-row[row-type='process'][row-id='${data.children[0].pid}'][folder]`
279        );
280      }
281      //@ts-ignore
282      sp.drawJankLine(endP, findJankEntry, data.children[0]);
283    }
284  }
285}
286
287function getEndStruct(data: unknown, sp: SpSystemTrace): unknown {
288  let endRowStruct: unknown;
289  //@ts-ignore
290  if (data.frameType === 'frameTime') {
291    endRowStruct = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
292      "trace-row[row-id='actual frameTime'][row-type='janks']"
293    );
294  } else {
295    endRowStruct = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
296      //@ts-ignore
297      `trace-row[row-id='${data.type}-${data.pid}'][row-type='janks']`
298    );
299  }
300  return endRowStruct;
301}
302
303function drawJankLineEndParent(
304  endParentRow: unknown,
305  sp: SpSystemTrace,
306  data: unknown,
307  startRow: unknown,
308  selectJankStruct: JankStruct,
309  isBinderClick: boolean = false
310): void {
311  if (isBinderClick) {
312    //@ts-ignore
313    endParentRow.expansion = true;
314  }
315  //终点的父泳道过滤出选中的Struct
316  let endRowStruct = getEndStruct(data, sp);
317  //泳道未展开的情况,查找endRowStruct
318  if (!endRowStruct) {
319    //@ts-ignore
320    if (data.frameType === 'frameTime') {
321      //@ts-ignore
322      endParentRow.childrenList.forEach((item: TraceRow<JankStruct>) => {
323        if (item.rowId === 'actual frameTime' && item.rowType === 'janks') {
324          endRowStruct = item;
325        }
326      });
327      //frameTime未展开
328      if (!endRowStruct) {
329        endParentRow = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>("trace-row[row-id='frameTime'][folder]");
330        //@ts-ignore
331        endParentRow?.childrenList?.forEach((item: TraceRow<JankStruct>): void => {
332          if (item.rowId === 'actual frameTime' && item.rowType === 'janks') {
333            endRowStruct = item;
334          }
335        });
336      }
337    } else {
338      //@ts-ignore
339      endParentRow.childrenList.forEach((item: TraceRow<JankStruct>) => {
340        if (item.name.startsWith('Actual Timeline') && item.rowType === 'janks') {
341          endRowStruct = item;
342        }
343      });
344    }
345  }
346  if (endRowStruct) {
347    //@ts-ignore
348    if (endRowStruct.isComplete) {
349      addPointLink(endParentRow, sp, data, startRow, selectJankStruct, endRowStruct);
350    } else {
351      //@ts-ignore
352      endRowStruct.supplierFrame!().then((res: unknown) => {
353        //@ts-ignore
354        endRowStruct.dataListCache = res;
355        //@ts-ignore
356        endRowStruct.loadingFrame = false;
357        addPointLink(endParentRow, sp, data, startRow, selectJankStruct, endRowStruct);
358      });
359    }
360  }
361}
362
363export function spSystemTraceDrawJankLine(
364  sp: SpSystemTrace,
365  endParentRow: unknown,
366  selectJankStruct: JankStruct,
367  data: unknown,
368  isBinderClick: boolean = false
369): void {
370  let collectList = sp.favoriteChartListEL!.getAllCollectRows();
371  let startRow: unknown;
372  if (!selectJankStruct) {
373    return;
374  }
375  let selectRowId = 'actual frameTime';
376  if (selectJankStruct.frameType === 'frameTime') {
377    startRow = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
378      `trace-row[row-id='${selectRowId}'][row-type='janks']`
379    );
380  } else {
381    selectRowId = `${selectJankStruct.type}-${selectJankStruct.pid}`;
382    startRow = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>(
383      `trace-row[row-id='${selectRowId}'][row-type='janks']`
384    );
385  }
386  if (!startRow) {
387    for (let collectChart of collectList) {
388      if (collectChart.rowId === selectRowId && collectChart.rowType === 'janks') {
389        startRow = collectChart;
390        break;
391      }
392    }
393  }
394  if (endParentRow) {
395    drawJankLineEndParent(endParentRow, sp, data, startRow, selectJankStruct, isBinderClick);
396  }
397}
398
399export function spSystemTraceDrawDistributedLine(
400  sp: SpSystemTrace,
401  sourceData: FuncStruct,
402  targetData: FuncStruct,
403  selectFuncStruct: FuncStruct,
404): void {
405  let collectList = sp.favoriteChartListEL!.getAllCollectRows() as TraceRow<BaseStruct>[];
406  if (!selectFuncStruct) {
407    return;
408  }
409  let sourceThreadRow;
410  let targetThreadRow;
411  let sourceRowId;
412  let targetRowId;
413  if (Utils.currentTraceMode === TraceMode.DISTRIBUTED) {
414    sourceRowId = `${sourceData.tid}-${sourceData.traceId}`;
415    targetRowId = `${targetData.tid}-${targetData.traceId}`;
416    sourceThreadRow = sp.shadowRoot?.querySelector(
417      `trace-row[row-id='${sourceRowId}'][row-type='func']`
418    ) as TraceRow<BaseStruct>;
419    targetThreadRow = sp.shadowRoot?.querySelector(
420      `trace-row[row-id='${targetRowId}'][row-type='func']`
421    ) as TraceRow<BaseStruct>;
422  } else {
423    sourceRowId = `${sourceData.tid}`;
424    targetRowId = `${targetData.tid}`;
425    sourceThreadRow = sp.shadowRoot?.querySelector(
426      `trace-row[row-id='${sourceData.tid}'][row-type='func']`
427    ) as TraceRow<BaseStruct>;
428    targetThreadRow = sp.shadowRoot?.querySelector(
429      `trace-row[row-id='${targetData.tid}'][row-type='func']`
430    ) as TraceRow<BaseStruct>;
431  }
432  if (!sourceThreadRow || !targetThreadRow) {
433    for (let collectChart of collectList) {
434      if (
435        !sourceThreadRow &&
436        (Utils.currentTraceMode !== TraceMode.DISTRIBUTED || collectChart.traceId === sourceData.traceId) &&
437        collectChart.rowId === sourceRowId &&
438        collectChart.rowType === 'func'
439      ) {
440        sourceThreadRow = collectChart;
441      }
442      if (
443        !targetThreadRow &&
444        (Utils.currentTraceMode !== TraceMode.DISTRIBUTED || collectChart.traceId === targetData.traceId) &&
445        collectChart.rowId === targetRowId &&
446        collectChart.rowType === 'func'
447      ) {
448        targetThreadRow = collectChart;
449      }
450    }
451  }
452  addPointHandle(sp, sourceData, sourceThreadRow, targetData, targetThreadRow, 'distributedLine');
453}
454
455function taskPoolOtherRelationData(
456  selectRow: unknown,
457  sp: SpSystemTrace,
458  //@ts-ignore
459  row: TraceRow<unknown>,
460  relationDataList: FuncStruct[],
461  res: unknown
462): void {
463  sp.clearPointPair();
464  //@ts-ignore
465  selectRow!.fixedList = relationDataList;
466  if (FuncStruct.selectFuncStruct === undefined || FuncStruct.selectFuncStruct === null) {
467    return;
468  }
469  relationDataList.forEach((value) => {
470    TabPaneTaskFrames.TaskArray.push(value);
471    // allocation to execute
472    const selectY = (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20;
473    const offSetY = (value.depth! + 0.5) * 20;
474    //@ts-ignore
475    const selectRowY = selectRow?.translateY!;
476    const selectStartTs = FuncStruct.selectFuncStruct!.startTs!;
477    const selectDur = FuncStruct.selectFuncStruct!.dur!;
478    //@ts-ignore
479    if (value.id === res[0].allocation_task_row) {
480      sp.addPointPair(
481        sp.makePoint(value.startTs!, 0, selectRowY, selectRow, offSetY, 'task', LineType.bezierCurve, true),
482        sp.makePoint(selectStartTs, 0, row?.translateY!, row, selectY, 'task', LineType.bezierCurve, true)
483      );
484    } else {
485      sp.addPointPair(
486        sp.makePoint(selectStartTs, selectDur, row?.translateY!, row, selectY, 'task', LineType.bezierCurve, false),
487        sp.makePoint(value.startTs!, value.dur!, selectRowY, selectRow, offSetY, 'task', LineType.bezierCurve, false)
488      );
489    }
490  });
491  sp.refreshCanvas(true);
492}
493
494function taskPoolRelationDataAllocation(
495  executeRow: TraceRow<FuncStruct> | null | undefined,
496  sp: SpSystemTrace,
497  //@ts-ignore
498  row: TraceRow<unknown>,
499  relationDataList: FuncStruct[],
500  res: unknown
501): void {
502  sp.clearPointPair();
503  if (FuncStruct.selectFuncStruct === undefined || FuncStruct.selectFuncStruct === null) {
504    return;
505  }
506  //@ts-ignore
507  let executeStruct = relationDataList.filter((item) => item.id === res[0].execute_task_row)[0];
508  relationDataList.forEach((value) => {
509    const selectY = (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20;
510    const offSetY = (value.depth! + 0.5) * 20;
511    const executeRowY = executeRow?.translateY!;
512    const selectStartTs = FuncStruct.selectFuncStruct!.startTs!;
513    const executeY = (executeStruct.depth! + 0.5) * 20;
514    TabPaneTaskFrames.TaskArray.push(value);
515    //@ts-ignore
516    if (value.id === res[0].execute_task_row) {
517      sp.addPointPair(
518        sp.makePoint(selectStartTs, 0, row?.translateY!, row, selectY, 'task', LineType.bezierCurve, true),
519        sp.makePoint(value.startTs!, 0, executeRowY, executeRow, offSetY, 'task', LineType.bezierCurve, true)
520      );
521    } else {
522      sp.addPointPair(
523        sp.makePoint(
524          executeStruct.startTs!,
525          executeStruct.dur!,
526          executeRowY,
527          executeRow,
528          executeY,
529          'task',
530          LineType.bezierCurve,
531          false
532        ),
533        sp.makePoint(value.startTs!, value.dur!, row?.translateY!, row, offSetY, 'task', LineType.bezierCurve, false)
534      );
535    }
536  });
537}
538
539function taskPoolRelationDataPerformTask(
540  executeRow: TraceRow<FuncStruct> | null | undefined,
541  sp: SpSystemTrace,
542  //@ts-ignore
543  row: TraceRow<unknown>,
544  relationDataList: FuncStruct[],
545  res: unknown
546): void {
547  sp.clearPointPair();
548  if (FuncStruct.selectFuncStruct === undefined || FuncStruct.selectFuncStruct === null) {
549    return;
550  }
551  //@ts-ignore
552  let executeStruct = relationDataList.filter((item) => item.id === res[0].execute_task_row)[0];
553  relationDataList.forEach((value) => {
554    const executeRowY = executeRow?.translateY!;
555    const selectStartTs = FuncStruct.selectFuncStruct!.startTs!;
556    const executeY = (executeStruct.depth! + 0.5) * 20;
557    const selectY = (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20;
558    const offSetY = (value.depth! + 0.5) * 20;
559    TabPaneTaskFrames.TaskArray.push(value);
560    //@ts-ignore
561    if (value.id === res[0].execute_task_row) {
562      sp.addPointPair(
563        sp.makePoint(
564          selectStartTs,
565          FuncStruct.selectFuncStruct!.dur!,
566          row?.translateY!,
567          row,
568          selectY,
569          'task',
570          LineType.bezierCurve,
571          false
572        ),
573        sp.makePoint(value.startTs!, value.dur!, executeRowY, executeRow, offSetY, 'task', LineType.bezierCurve, false)
574      );
575    } else {
576      sp.addPointPair(
577        sp.makePoint(executeStruct.startTs!, 0, executeRowY, executeRow, executeY, 'task', LineType.bezierCurve, true),
578        sp.makePoint(value.startTs!, 0, row?.translateY!, row, offSetY, 'task', LineType.bezierCurve, true)
579      );
580    }
581  });
582  sp.refreshCanvas(true);
583}
584
585//@ts-ignore
586function taskAllocationOrPerformTask(sp: SpSystemTrace, row: TraceRow<unknown>, executeID: string): void {
587  TabPaneTaskFrames.IsShowConcurrency = false;
588  sp.clearPointPair();
589  queryBySelectAllocationOrReturn(executeID, FuncStruct.selectFuncStruct!.itid!).then((res) => {
590    if (!FuncStruct.selectFuncStruct) {
591      return;
592    }
593    if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task Allocation:') >= 0 && res.length > 0) {
594      let executeRow = sp.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
595        `trace-row[row-id='${res[0].tid}'][row-type='func']`
596      );
597      if (!executeRow) {
598        return;
599      }
600      let idList: number[] = [];
601      let tidList: number[] = [];
602      if (res[0].execute_task_row) {
603        idList.push(res[0].execute_task_row);
604        tidList.push(Number(res[0].tid));
605      }
606      if (res[0].return_task_row) {
607        idList.push(res[0].return_task_row);
608        tidList.push(Number(row.rowId));
609      }
610      queryTaskPoolRelationData(idList, tidList).then((relationDataList) => {
611        taskPoolRelationDataAllocation(executeRow, sp, row, relationDataList, res);
612      });
613    } else if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task PerformTask End:') >= 0) {
614      let executeRow = sp.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
615        `trace-row[row-id='${res[0].tid}'][row-type='func']`
616      );
617      TabPaneTaskFrames.TaskArray.push(FuncStruct.selectFuncStruct!);
618      let idList: number[] = [];
619      let tidList: number[] = [];
620      if (res[0].execute_task_row) {
621        idList.push(res[0].execute_task_row);
622        tidList.push(Number(res[0].tid));
623      }
624      if (res[0].allocation_task_row) {
625        idList.push(res[0].allocation_task_row);
626        tidList.push(Number(row.rowId));
627      }
628      queryTaskPoolRelationData(idList, tidList).then((relationDataList) => {
629        taskPoolRelationDataPerformTask(executeRow, sp, row, relationDataList, res);
630      });
631    }
632  });
633}
634
635//@ts-ignore
636export function spSystemTraceDrawTaskPollLine(sp: SpSystemTrace, row?: TraceRow<unknown>): void {
637  if (FuncStruct.selectFuncStruct === undefined || FuncStruct.selectFuncStruct === null) {
638    return;
639  }
640  let relationId = TabPaneTaskFrames.getRelationId(FuncStruct.selectFuncStruct!.funName!);
641  TabPaneTaskFrames.TaskArray.push(FuncStruct.selectFuncStruct!);
642  if (!row) {
643    return;
644  }
645  if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task Perform:') >= 0) {
646    TabPaneTaskFrames.IsShowConcurrency = true;
647    queryBySelectExecute(relationId, FuncStruct.selectFuncStruct!.itid!).then((res) => {
648      if (res.length === 1) {
649        let allocationRowId = res[0].tid;
650        let selectRow = sp.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
651          `trace-row[row-id='${allocationRowId}'][row-type='func']`
652        );
653        if (!selectRow) {
654          let collectList = sp.favoriteChartListEL!.getAllCollectRows();
655          for (let selectCollectRow of collectList) {
656            if (selectCollectRow.rowId === allocationRowId.toString() && selectCollectRow.rowType === 'func') {
657              // @ts-ignore
658              selectRow = selectCollectRow;
659              break;
660            }
661          }
662        }
663        let idList: number[] = [];
664        if (res[0].allocation_task_row) {
665          idList.push(res[0].allocation_task_row);
666        }
667        if (res[0].return_task_row) {
668          idList.push(res[0].return_task_row);
669        }
670        queryTaskPoolOtherRelationData(idList, allocationRowId).then((relationDataList) => {
671          taskPoolOtherRelationData(selectRow, sp, row, relationDataList, res);
672        });
673      }
674    });
675  } else {
676    taskAllocationOrPerformTask(sp, row, relationId);
677  }
678}
679
680function jankPoint(
681  endRowStruct: unknown,
682  selectThreadStruct: ThreadStruct,
683  startRow: unknown,
684  endParentRow: unknown,
685  sp: SpSystemTrace
686): void {
687  //@ts-ignore
688  let findJankEntry = endRowStruct!.fixedList[0];
689  let ts: number = 0;
690  if (findJankEntry) {
691    ts = selectThreadStruct.startTime! + selectThreadStruct.dur! / 2;
692    const [startY, startRowEl, startOffSetY] = sp.calculateStartY(startRow, selectThreadStruct.pid);
693    const [endY, endRowEl, endOffSetY] = sp.calculateEndY(endParentRow, endRowStruct);
694    sp.addPointPair(
695      sp.makePoint(
696        ns2xByTimeShaft(ts, sp.timerShaftEL!),
697        ts,
698        startY,
699        startRowEl!,
700        startOffSetY,
701        'thread',
702        LineType.straightLine,
703        selectThreadStruct.startTime === ts
704      ),
705      sp.makePoint(
706        ns2xByTimeShaft(findJankEntry.startTime!, sp.timerShaftEL!),
707        findJankEntry.startTime!,
708        endY,
709        endRowEl,
710        endOffSetY,
711        'thread',
712        LineType.straightLine,
713        true
714      )
715    );
716  }
717}
718
719function junkBinder(
720  endRowStruct: unknown,
721  selectFuncStruct: FuncStruct,
722  startRow: unknown,
723  endParentRow: unknown,
724  sp: SpSystemTrace,
725  data: unknown
726): void {
727  // @ts-ignore
728  let findJankEntry = endRowStruct!.fixedList[0];
729  let ts: number = 0;
730  if (findJankEntry) {
731    ts = selectFuncStruct.startTs! + selectFuncStruct.dur! / 2;
732    const [startY, startRowEl, startOffSetY] = sp.calculateStartY(startRow, selectFuncStruct.pid, selectFuncStruct);
733    const [endY, endRowEl, endOffSetY] = sp.calculateEndY(endParentRow, endRowStruct, data);
734    sp.addPointPair(
735      sp.makePoint(
736        ns2xByTimeShaft(ts, sp.timerShaftEL!),
737        ts,
738        startY,
739        startRowEl!,
740        startOffSetY,
741        'func',
742        LineType.straightLine,
743        selectFuncStruct.startTs === ts
744      ),
745      sp.makePoint(
746        ns2xByTimeShaft(findJankEntry.startTs!, sp.timerShaftEL!),
747        findJankEntry.startTs!,
748        endY,
749        endRowEl,
750        endOffSetY,
751        'func',
752        LineType.straightLine,
753        true
754      )
755    );
756  }
757}
758
759export function spSystemTraceDrawThreadLine(
760  sp: SpSystemTrace,
761  endParentRow: unknown,
762  selectThreadStruct: ThreadStruct | undefined,
763  data: unknown
764): void {
765  let collectList = sp.favoriteChartListEL!.getCollectRows();
766  if (!selectThreadStruct) {
767    return;
768  }
769  let selectRowId = selectThreadStruct.tid;
770  let startRow = sp.getStartRow(selectRowId, collectList);
771
772  if (endParentRow) {
773    //@ts-ignore
774    endParentRow.expansion = true;
775    let endRowStruct: unknown = sp.shadowRoot?.querySelector<TraceRow<ThreadStruct>>(
776      //@ts-ignore
777      `trace-row[row-id='${data.tid}'][row-type='thread']`
778    );
779    if (!endRowStruct) {
780      //@ts-ignore
781      endRowStruct = endParentRow.childrenList.find((item: TraceRow<ThreadStruct>) => {
782        //@ts-ignore
783        return item.rowId === `${data.tid}` && item.rowType === 'thread';
784      });
785    }
786    if (endRowStruct) {
787      //@ts-ignore
788      if (endRowStruct.isComplete) {
789        jankPoint(endRowStruct, selectThreadStruct, startRow, endParentRow, sp);
790      }
791    }
792  }
793}
794
795export function spSystemTraceDrawFuncLine(
796  sp: SpSystemTrace,
797  endParentRow: unknown,
798  selectFuncStruct: FuncStruct | undefined,
799  data: unknown,
800  binderTid: Number
801): void {
802  let collectList = sp.favoriteChartListEL!.getCollectRows();
803  if (selectFuncStruct === undefined || selectFuncStruct === null) {
804    return;
805  }
806  let selectRowId = selectFuncStruct?.tid ? selectFuncStruct?.tid : binderTid.toString();
807  let startRow = sp.shadowRoot?.querySelector<TraceRow<FuncStruct>>(`trace-row[row-id='${selectRowId}'][row-type='func']`);
808  if (!startRow) {
809    for (let collectChart of collectList) {
810      if (collectChart.rowId === selectRowId.toString() && collectChart.rowType === 'func') {
811        startRow = collectChart as TraceRow<FuncStruct>;
812        break;
813      }
814    }
815  }
816  if (endParentRow) {
817    // @ts-ignore
818    endParentRow.expansion = true;
819    let endRowStruct: unknown = sp.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
820      // @ts-ignore
821      `trace-row[row-id='${data.tid}'][row-type='func']`
822    );
823    if (!endRowStruct) {
824      // @ts-ignore
825      endRowStruct = endParentRow.childrenList.find((item: TraceRow<FuncStruct>) => {
826        // @ts-ignore
827        return item.rowId === `${data.tid}` && item.rowType === 'func';
828      });
829    }
830    if (endRowStruct) {
831      junkBinder(endRowStruct, selectFuncStruct, startRow, endParentRow, sp, data);
832    }
833  }
834}
835