• 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 { info } from '../../../log/Log';
18import { TraceRow } from '../trace/base/TraceRow';
19import { Utils } from '../trace/base/Utils';
20import { type EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU';
21import { type ProcessStruct } from '../../database/ui-worker/ProcedureWorkerProcess';
22import { CpuAbilityMonitorStruct, CpuAbilityRender } from '../../database/ui-worker/ProcedureWorkerCpuAbility';
23import { MemoryAbilityMonitorStruct, MemoryAbilityRender } from '../../database/ui-worker/ProcedureWorkerMemoryAbility';
24import { DiskAbilityMonitorStruct, DiskIoAbilityRender } from '../../database/ui-worker/ProcedureWorkerDiskIoAbility';
25import {
26  NetworkAbilityMonitorStruct,
27  NetworkAbilityRender,
28} from '../../database/ui-worker/ProcedureWorkerNetworkAbility';
29import { renders } from '../../database/ui-worker/ProcedureWorker';
30import { type SnapshotRender, SnapshotStruct } from '../../database/ui-worker/ProcedureWorkerSnapshot';
31import {
32  abilityBytesInTraceDataSender,
33  abilityBytesReadDataSender,
34  abilityMemoryUsedDataSender,
35  cpuAbilityUserDataSender,
36} from '../../database/data-trafic/AbilityMonitorSender';
37import {
38  abilityDmaDataSender,
39  abilityGpuMemoryDataSender,
40  abilityPurgeableDataSender,
41} from '../../database/data-trafic/VmTrackerDataSender';
42import { MemoryConfig } from '../../bean/MemoryConfig';
43import { queryMemoryMaxData } from '../../database/sql/Memory.sql';
44import { queryDiskIoMaxData, queryNetWorkMaxData } from '../../database/sql/SqlLite.sql';
45import { queryAbilityExits, queryCPuAbilityMaxData, queryPurgeableSysData } from '../../database/sql/Ability.sql';
46import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil';
47const networkNameList: Array<string> = ['Bytes In/Sec', 'Bytes Out/Sec', 'Packets In/Sec', 'Packets Out/Sec'];
48const memoryNameList: Array<string> = ['MemoryTotal', 'Cached', 'SwapTotal'];
49const diskIONameList: Array<string> = ['Bytes Read/Sec', 'Bytes Written/Sec', 'Read Ops/Sec', 'Written Ops/Sec'];
50const key = 'abilityMonitor';
51export class SpAbilityMonitorChart {
52  private trace: SpSystemTrace;
53  constructor(trace: SpSystemTrace) {
54    this.trace = trace;
55  }
56  memoryMath = (maxByte: number): string => {
57    let maxByteName = '';
58    if (maxByte > 0) {
59      maxByteName = Utils.getBinaryKBWithUnit(maxByte);
60    }
61    return maxByteName;
62  };
63
64  diskIOMath = (maxByte: number): string => {
65    let maxByteName = '';
66    if (maxByte > 0) {
67      maxByteName = `${maxByte}KB/S`;
68    }
69    return maxByteName;
70  };
71
72  networkMath = (maxValue: number): string => {
73    let maxByteName = '';
74    if (maxValue > 0) {
75      maxByteName = Utils.getBinaryByteWithUnit(maxValue);
76    }
77    return maxByteName;
78  };
79
80  async init(): Promise<void> {
81    let time = new Date().getTime();
82    let result = await queryAbilityExits();
83    info('Ability Monitor Exits Tables size is: ', result!.length);
84    if (result.length <= 0) {
85      return;
86    }
87    let processRow = this.initAbilityRow();
88    if (this.hasTable(result, 'trace_cpu_usage')) {
89      await this.initCpuAbility(processRow);
90    }
91    if (this.hasTable(result, 'sys_memory')) {
92      await this.initMemoryAbility(processRow);
93    }
94    if (this.hasTable(result, 'trace_diskio')) {
95      await this.initDiskAbility(processRow);
96    }
97    if (this.hasTable(result, 'trace_network')) {
98      await this.initNetworkAbility(processRow);
99    }
100    // 初始化PurgeableToTal和PurgeablePin泳道图
101    let totalDataList = await queryPurgeableSysData(false);
102    let pinDataList = await queryPurgeableSysData(true);
103    if (totalDataList.length > 0) {
104      await this.initPurgeableTotal(processRow);
105    }
106    if (pinDataList.length > 0) {
107      await this.initPurgeablePin(processRow);
108    }
109    await this.initDmaAbility(processRow);
110    await this.initGpuMemoryAbility(processRow);
111    let durTime = new Date().getTime() - time;
112    info('The time to load the AbilityMonitor data is: ', durTime);
113  }
114
115  private hasTable(result: Array<unknown>, tableName: string): boolean {
116    // @ts-ignore
117    return result.find((o) => {
118      // @ts-ignore
119      return o.event_name === tableName;
120    });
121  }
122
123  private initAbilityRow = (): TraceRow<ProcessStruct> => {
124    let abilityRow = TraceRow.skeleton<ProcessStruct>();
125    abilityRow.rowId = key;
126    abilityRow.rowType = TraceRow.ROW_TYPE_MONITOR;
127    abilityRow.style.height = '40px';
128    abilityRow.rowParentId = '';
129    abilityRow.folder = true;
130    abilityRow.name = 'Ability Monitor';
131    abilityRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
132    abilityRow.selectChangeHandler = this.trace.selectChangeHandler; // @ts-ignore
133    abilityRow.supplier = (): Promise<unknown[]> => new Promise<Array<unknown>>((resolve) => resolve([]));
134    abilityRow.onThreadHandler = (useCache): void => {
135      let context: CanvasRenderingContext2D;
136      if (abilityRow.currentContext) {
137        context = abilityRow.currentContext;
138      } else {
139        context = abilityRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
140      }
141      abilityRow.canvasSave(context);
142      if (abilityRow.expansion) {
143        // @ts-ignore
144        context?.clearRect(0, 0, abilityRow.frame.width, abilityRow.frame.height);
145      } else {
146        (renders.empty as EmptyRender).renderMainThread(
147          {
148            context: context,
149            useCache: useCache,
150            type: '',
151          },
152          abilityRow
153        );
154      }
155      abilityRow.canvasRestore(context, this.trace);
156    };
157    this.trace.rowsEL?.appendChild(abilityRow);
158    return abilityRow;
159  };
160
161  private initCpuAbility = async (processRow: TraceRow<ProcessStruct>): Promise<void> => {
162    let time = new Date().getTime();
163    let cpuMaxData = await queryCPuAbilityMaxData();
164    let hasTotal = false;
165    let hasUserLoad = false;
166    let hasSystemLoad = false;
167    //@ts-ignore
168    let userLoad = cpuMaxData[0].userLoad;
169    if (userLoad > 0) {
170      hasUserLoad = true;
171    } //@ts-ignore
172    let systemLoad = cpuMaxData[0].systemLoad;
173    if (systemLoad > 0) {
174      hasSystemLoad = true;
175    } //@ts-ignore
176    let totalLoad = cpuMaxData[0].totalLoad;
177    if (totalLoad > 0) {
178      hasTotal = true;
179    }
180    let cpuNameList: Array<string> = ['Total', 'User', 'System'];
181    this.initTotalMonitorTraceRow(processRow, cpuNameList, hasTotal);
182    this.initUserMonitorTraceRow(processRow, cpuNameList, hasUserLoad);
183    this.initSysMonitorTraceRow(processRow, cpuNameList, hasSystemLoad);
184    let durTime = new Date().getTime() - time;
185    info('The time to load the Ability Cpu is: ', durTime);
186  };
187
188  private initUserMonitorTraceRow(processRow: TraceRow<ProcessStruct>, cpuList: Array<string>, load: boolean): void {
189    let userTraceRow = TraceRow.skeleton<CpuAbilityMonitorStruct>();
190    userTraceRow.rowParentId = key;
191    userTraceRow.rowHidden = !processRow.expansion;
192    userTraceRow.rowId = cpuList[1];
193    userTraceRow.rowType = TraceRow.ROW_TYPE_CPU_ABILITY;
194    userTraceRow.style.height = '40px';
195    userTraceRow.style.width = '100%';
196    userTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
197    userTraceRow.selectChangeHandler = this.trace.selectChangeHandler;
198    userTraceRow.setAttribute('children', '');
199    userTraceRow.name = `CPU ${cpuList[1]} Load`;
200    userTraceRow.supplierFrame = (): Promise<CpuAbilityMonitorStruct[]> =>
201      cpuAbilityUserDataSender(userTraceRow, 'CpuAbilityUserData').then((res): CpuAbilityMonitorStruct[] => {
202        this.computeDur(res);
203        return res;
204      });
205    userTraceRow.focusHandler = (ev): void => {
206      let monitorCpuTip = `${(CpuAbilityMonitorStruct.hoverCpuAbilityStruct?.value || 0).toFixed(2)}%`;
207      this.trace?.displayTip(
208        userTraceRow,
209        CpuAbilityMonitorStruct.hoverCpuAbilityStruct,
210        `<span>${monitorCpuTip}</span>`
211      );
212    };
213    userTraceRow.findHoverStruct = (): void => {
214      CpuAbilityMonitorStruct.hoverCpuAbilityStruct = userTraceRow.getHoverStruct();
215    };
216    userTraceRow.onThreadHandler = (useCache): void => {
217      let context: CanvasRenderingContext2D;
218      if (userTraceRow.currentContext) {
219        context = userTraceRow.currentContext;
220      } else {
221        context = userTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
222      }
223      userTraceRow.canvasSave(context);
224      (renders.monitorCpu as CpuAbilityRender).renderMainThread(
225        {
226          context: context,
227          useCache: useCache,
228          type: 'monitorCpu1',
229          maxCpuUtilization: 100,
230          maxCpuUtilizationName: load ? '100%' : '0%',
231        },
232        userTraceRow
233      );
234      userTraceRow.canvasRestore(context, this.trace);
235    };
236    processRow.addChildTraceRow(userTraceRow);
237  }
238
239  private initTotalMonitorTraceRow(parent: TraceRow<ProcessStruct>, cpuList: Array<string>, hasTotal: boolean): void {
240    let traceRow = TraceRow.skeleton<CpuAbilityMonitorStruct>();
241    traceRow.rowParentId = key;
242    traceRow.rowHidden = !parent.expansion;
243    traceRow.rowId = cpuList[0];
244    traceRow.rowType = TraceRow.ROW_TYPE_CPU_ABILITY;
245    traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
246    traceRow.selectChangeHandler = this.trace.selectChangeHandler;
247    traceRow.style.height = '40px';
248    traceRow.style.width = '100%';
249    traceRow.setAttribute('children', '');
250    traceRow.name = `CPU ${cpuList[0]} Load`;
251    traceRow.supplierFrame = (): Promise<CpuAbilityMonitorStruct[]> =>
252      cpuAbilityUserDataSender(traceRow, 'CpuAbilityMonitorData').then((res): CpuAbilityMonitorStruct[] => {
253        this.computeDur(res);
254        return res;
255      });
256    traceRow.focusHandler = (ev): void => {
257      let monitorCpuTip = `${(CpuAbilityMonitorStruct.hoverCpuAbilityStruct?.value || 0).toFixed(2)}'%'`;
258      this.trace?.displayTip(traceRow, CpuAbilityMonitorStruct.hoverCpuAbilityStruct, `<span>${monitorCpuTip}</span>`);
259    };
260    traceRow.findHoverStruct = (): void => {
261      CpuAbilityMonitorStruct.hoverCpuAbilityStruct = traceRow.getHoverStruct();
262    };
263    traceRow.onThreadHandler = (useCache): void => {
264      let context: CanvasRenderingContext2D;
265      if (traceRow.currentContext) {
266        context = traceRow.currentContext;
267      } else {
268        context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
269      }
270      traceRow.canvasSave(context);
271      (renders.monitorCpu as CpuAbilityRender).renderMainThread(
272        {
273          context: context,
274          useCache: useCache,
275          type: 'monitorCpu0',
276          maxCpuUtilization: 100,
277          maxCpuUtilizationName: hasTotal ? '100%' : '0%',
278        },
279        traceRow
280      );
281      traceRow.canvasRestore(context, this.trace);
282    };
283    parent.addChildTraceRow(traceRow);
284  }
285
286  private initSysMonitorTraceRow(parent: TraceRow<ProcessStruct>, cpuList: Array<string>, hasLoad: boolean): void {
287    let sysTraceRow = TraceRow.skeleton<CpuAbilityMonitorStruct>();
288    sysTraceRow.rowParentId = key;
289    sysTraceRow.rowHidden = !parent.expansion;
290    sysTraceRow.rowId = cpuList[2];
291    sysTraceRow.rowType = TraceRow.ROW_TYPE_CPU_ABILITY;
292    sysTraceRow.style.height = '40px';
293    sysTraceRow.style.width = '100%';
294    sysTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
295    sysTraceRow.selectChangeHandler = this.trace.selectChangeHandler;
296    sysTraceRow.setAttribute('children', '');
297    sysTraceRow.name = `CPU ${cpuList[2]} Load`;
298    sysTraceRow.supplierFrame = (): Promise<CpuAbilityMonitorStruct[]> =>
299      cpuAbilityUserDataSender(sysTraceRow, 'CpuAbilitySystemData').then((res): CpuAbilityMonitorStruct[] => {
300        this.computeDur(res);
301        return res;
302      });
303    sysTraceRow.focusHandler = (): void => {
304      this.trace?.displayTip(
305        sysTraceRow,
306        CpuAbilityMonitorStruct.hoverCpuAbilityStruct,
307        `<span>${(CpuAbilityMonitorStruct.hoverCpuAbilityStruct?.value || 0).toFixed(2)}%</span>`
308      );
309    };
310    sysTraceRow.findHoverStruct = (): void => {
311      CpuAbilityMonitorStruct.hoverCpuAbilityStruct = sysTraceRow.getHoverStruct();
312    };
313    sysTraceRow.onThreadHandler = (useCache): void => {
314      let context: CanvasRenderingContext2D;
315      if (sysTraceRow.currentContext) {
316        context = sysTraceRow.currentContext;
317      } else {
318        context = sysTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
319      }
320      sysTraceRow.canvasSave(context);
321      (renders.monitorCpu as CpuAbilityRender).renderMainThread(
322        {
323          context: context,
324          useCache: useCache,
325          type: 'monitorCpu2',
326          maxCpuUtilization: 100,
327          maxCpuUtilizationName: hasLoad ? '100%' : '0%',
328        },
329        sysTraceRow
330      );
331      sysTraceRow.canvasRestore(context, this.trace);
332    };
333    parent.addChildTraceRow(sysTraceRow);
334  }
335
336  private memoryUsedThreadHandle(memoryUsedRow: TraceRow<MemoryAbilityMonitorStruct>, memoryTotal: unknown[]): void {
337    // @ts-ignore
338    let memoryTotalValue = memoryTotal[0].maxValue;
339    let memoryTotalValueName = this.memoryMath(memoryTotalValue);
340    memoryUsedRow.onThreadHandler = (useCache): void => {
341      let context: CanvasRenderingContext2D;
342      if (memoryUsedRow.currentContext) {
343        context = memoryUsedRow.currentContext;
344      } else {
345        context = memoryUsedRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
346      }
347      memoryUsedRow.canvasSave(context);
348      (renders.monitorMemory as MemoryAbilityRender).renderMainThread(
349        {
350          context: context,
351          useCache: useCache,
352          type: 'monitorMemory0',
353          maxMemoryByte: memoryTotalValue,
354          maxMemoryByteName: memoryTotalValueName,
355        },
356        memoryUsedRow
357      );
358      memoryUsedRow.canvasRestore(context, this.trace);
359    };
360  }
361
362  private async initMemoryUsedRow(
363    memoryUsedRow: TraceRow<MemoryAbilityMonitorStruct>, // @ts-ignore
364    parent: TraceRow<unknown>
365  ): Promise<void> {
366    let memoryTotal = await queryMemoryMaxData('sys.mem.total');
367    //@ts-ignore
368    let memoryTotalId = memoryTotal[0].filter_id;
369
370    memoryUsedRow.rowParentId = key;
371    memoryUsedRow.rowHidden = !parent.expansion;
372    memoryUsedRow.rowId = memoryNameList[0];
373    memoryUsedRow.rowType = TraceRow.ROW_TYPE_MEMORY_ABILITY;
374    memoryUsedRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
375    memoryUsedRow.selectChangeHandler = this.trace.selectChangeHandler;
376    memoryUsedRow.style.height = '40px';
377    memoryUsedRow.style.width = '100%';
378    memoryUsedRow.setAttribute('children', '');
379    memoryUsedRow.name = memoryNameList[0];
380    memoryUsedRow.supplierFrame = (): Promise<MemoryAbilityMonitorStruct[]> => {
381      return abilityMemoryUsedDataSender(memoryTotalId, memoryUsedRow).then((res): MemoryAbilityMonitorStruct[] => {
382        this.computeDur(res);
383        return res;
384      });
385    };
386    memoryUsedRow.focusHandler = (ev): void => {
387      this.trace?.displayTip(
388        memoryUsedRow,
389        MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct,
390        `<span>${Utils.getBinaryKBWithUnit(MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct?.value || 0)}</span>`
391      );
392    };
393    memoryUsedRow.findHoverStruct = (): void => {
394      MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = memoryUsedRow.getHoverStruct();
395    };
396    this.memoryUsedThreadHandle(memoryUsedRow, memoryTotal);
397  }
398
399  private cachedThreadHandler(cachedFilesTraceRow: TraceRow<MemoryAbilityMonitorStruct>, cached: unknown[]): void {
400    // @ts-ignore
401    let cachedValue = cached[0].maxValue;
402    let cachedValueName = this.memoryMath(cachedValue);
403    cachedFilesTraceRow.onThreadHandler = (useCache): void => {
404      let context: CanvasRenderingContext2D;
405      if (cachedFilesTraceRow.currentContext) {
406        context = cachedFilesTraceRow.currentContext;
407      } else {
408        context = cachedFilesTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
409      }
410      cachedFilesTraceRow.canvasSave(context);
411      (renders.monitorMemory as MemoryAbilityRender).renderMainThread(
412        {
413          context: context,
414          useCache: useCache,
415          type: 'monitorMemory1',
416          maxMemoryByte: cachedValue,
417          maxMemoryByteName: cachedValueName,
418        },
419        cachedFilesTraceRow
420      );
421      cachedFilesTraceRow.canvasRestore(context, this.trace);
422    };
423  }
424
425  private async initCachedRow(
426    cachedFilesRow: TraceRow<MemoryAbilityMonitorStruct>, // @ts-ignore
427    parent: TraceRow<unknown>
428  ): Promise<void> {
429    let cached = await queryMemoryMaxData('sys.mem.cached');
430
431    //@ts-ignore
432    let cachedId = cached[0].filter_id;
433    cachedFilesRow.rowParentId = key;
434    cachedFilesRow.rowHidden = !parent.expansion;
435    cachedFilesRow.rowId = memoryNameList[1];
436    cachedFilesRow.rowType = TraceRow.ROW_TYPE_MEMORY_ABILITY;
437    cachedFilesRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
438    cachedFilesRow.selectChangeHandler = this.trace.selectChangeHandler;
439    cachedFilesRow.style.height = '40px';
440    cachedFilesRow.style.width = '100%';
441    cachedFilesRow.setAttribute('children', '');
442    cachedFilesRow.name = memoryNameList[1];
443    cachedFilesRow.supplierFrame = (): Promise<MemoryAbilityMonitorStruct[]> =>
444      abilityMemoryUsedDataSender(cachedId, cachedFilesRow).then((res): MemoryAbilityMonitorStruct[] => {
445        this.computeDur(res);
446        return res;
447      });
448    cachedFilesRow.focusHandler = (ev): void => {
449      this.trace?.displayTip(
450        cachedFilesRow,
451        MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct,
452        `<span>${Utils.getBinaryKBWithUnit(MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct?.value || 0)}</span>`
453      );
454    };
455    cachedFilesRow.findHoverStruct = (): void => {
456      MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = cachedFilesRow.getHoverStruct();
457    };
458    this.cachedThreadHandler(cachedFilesRow, cached);
459  }
460
461  private compressThreadHandler(compressedRow: TraceRow<MemoryAbilityMonitorStruct>, swap: unknown[]): void {
462    // @ts-ignore
463    let swapValue = swap[0].maxValue;
464    let swapValueName = this.memoryMath(swapValue);
465    compressedRow.onThreadHandler = (useCache): void => {
466      let context: CanvasRenderingContext2D;
467      if (compressedRow.currentContext) {
468        context = compressedRow.currentContext;
469      } else {
470        context = compressedRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
471      }
472      compressedRow.canvasSave(context);
473      (renders.monitorMemory as MemoryAbilityRender).renderMainThread(
474        {
475          context: context,
476          useCache: useCache,
477          type: 'monitorMemory2',
478          maxMemoryByte: swapValue,
479          maxMemoryByteName: swapValueName,
480        },
481        compressedRow
482      );
483      compressedRow.canvasRestore(context, this.trace);
484    };
485  }
486
487  private async initCompressedRow(
488    compressedRow: TraceRow<MemoryAbilityMonitorStruct>, // @ts-ignore
489    parent: TraceRow<unknown>
490  ): Promise<void> {
491    let swap = await queryMemoryMaxData('sys.mem.swap.total');
492    //@ts-ignore
493    let swapId = swap[0].filter_id;
494    compressedRow.rowParentId = key;
495    compressedRow.rowHidden = !parent.expansion;
496    compressedRow.rowId = memoryNameList[2];
497    compressedRow.rowType = TraceRow.ROW_TYPE_MEMORY_ABILITY;
498    compressedRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
499    compressedRow.selectChangeHandler = this.trace.selectChangeHandler;
500    compressedRow.style.height = '40px';
501    compressedRow.style.width = '100%';
502    compressedRow.setAttribute('children', '');
503    compressedRow.name = memoryNameList[2];
504    compressedRow.supplierFrame = (): Promise<MemoryAbilityMonitorStruct[]> =>
505      abilityMemoryUsedDataSender(swapId, compressedRow).then((res): MemoryAbilityMonitorStruct[] => {
506        this.computeDur(res);
507        return res;
508      });
509    compressedRow.focusHandler = (ev): void => {
510      this.trace?.displayTip(
511        compressedRow,
512        MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct,
513        `<span>${Utils.getBinaryKBWithUnit(MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct?.value || 0)}</span>`
514      );
515    };
516    compressedRow.findHoverStruct = (): void => {
517      MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = compressedRow.getHoverStruct();
518    };
519    this.compressThreadHandler(compressedRow, swap);
520  }
521
522  private initMemoryAbility = async (processRow: TraceRow<ProcessStruct>): Promise<void> => {
523    let time = new Date().getTime();
524    // sys.mem.total  sys.mem.cached  sys.mem.swap.total
525    let memoryUsedTraceRow = TraceRow.skeleton<MemoryAbilityMonitorStruct>();
526    this.initMemoryUsedRow(memoryUsedTraceRow, processRow);
527    processRow.addChildTraceRow(memoryUsedTraceRow);
528
529    let cachedFilesTraceRow = TraceRow.skeleton<MemoryAbilityMonitorStruct>();
530    this.initCachedRow(cachedFilesTraceRow, processRow);
531    processRow.addChildTraceRow(cachedFilesTraceRow);
532
533    let compressedTraceRow = TraceRow.skeleton<MemoryAbilityMonitorStruct>();
534    this.initCompressedRow(compressedTraceRow, processRow);
535    processRow.addChildTraceRow(compressedTraceRow);
536    let durTime = new Date().getTime() - time;
537    info('The time to load the Ability Memory is: ', durTime);
538  };
539
540  private bytesReadThreadHandler(bytesReadRow: TraceRow<DiskAbilityMonitorStruct>, maxList: unknown[]): void {
541    // @ts-ignore
542    let maxBytesRead = maxList[0].bytesRead;
543    let maxBytesReadName = this.diskIOMath(maxBytesRead);
544    bytesReadRow.onThreadHandler = (useCache): void => {
545      let context: CanvasRenderingContext2D;
546      if (bytesReadRow.currentContext) {
547        context = bytesReadRow.currentContext;
548      } else {
549        context = bytesReadRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
550      }
551      bytesReadRow.canvasSave(context);
552      (renders.monitorDiskIo as DiskIoAbilityRender).renderMainThread(
553        {
554          context: context,
555          useCache: useCache,
556          type: 'monitorDiskIo0',
557          maxDiskRate: maxBytesRead,
558          maxDiskRateName: maxBytesReadName,
559        },
560        bytesReadRow
561      );
562      bytesReadRow.canvasRestore(context, this.trace);
563    };
564  }
565
566  private initBytesReadRow(
567    bytesReadRow: TraceRow<DiskAbilityMonitorStruct>, // @ts-ignore
568    parentRow: TraceRow<unknown>,
569    maxList: unknown[]
570  ): void {
571    bytesReadRow.rowParentId = key;
572    bytesReadRow.rowHidden = !parentRow.expansion;
573    bytesReadRow.rowId = diskIONameList[0];
574    bytesReadRow.rowType = TraceRow.ROW_TYPE_DISK_ABILITY;
575    bytesReadRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
576    bytesReadRow.selectChangeHandler = this.trace.selectChangeHandler;
577    bytesReadRow.style.height = '40px';
578    bytesReadRow.style.width = '100%';
579    bytesReadRow.setAttribute('children', '');
580    bytesReadRow.name = `Disk ${diskIONameList[0]}`;
581    bytesReadRow.supplierFrame = (): Promise<DiskAbilityMonitorStruct[]> =>
582      abilityBytesReadDataSender(bytesReadRow, 'AbilityBytesReadData').then((res): DiskAbilityMonitorStruct[] => {
583        this.computeDur(res);
584        return res;
585      });
586    bytesReadRow.focusHandler = (ev): void => {
587      this.trace?.displayTip(
588        bytesReadRow,
589        DiskAbilityMonitorStruct.hoverDiskAbilityStruct,
590        `<span>${DiskAbilityMonitorStruct.hoverDiskAbilityStruct?.value || '0'} KB/S</span>`
591      );
592    };
593    bytesReadRow.findHoverStruct = (): void => {
594      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = bytesReadRow.getHoverStruct();
595    };
596    this.bytesReadThreadHandler(bytesReadRow, maxList);
597  }
598  private bytesWriteThreadHandler(bytesWriteRow: TraceRow<DiskAbilityMonitorStruct>, maxList: unknown[]): void {
599    // @ts-ignore
600    let maxBytesWrite = maxList[0].bytesWrite;
601    let maxBytesWriteName = this.diskIOMath(maxBytesWrite);
602    bytesWriteRow.onThreadHandler = (useCache): void => {
603      let context: CanvasRenderingContext2D;
604      if (bytesWriteRow.currentContext) {
605        context = bytesWriteRow.currentContext;
606      } else {
607        context = bytesWriteRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
608      }
609      bytesWriteRow.canvasSave(context);
610      (renders.monitorDiskIo as DiskIoAbilityRender).renderMainThread(
611        {
612          context: context,
613          useCache: useCache,
614          type: 'monitorDiskIo1',
615          maxDiskRate: maxBytesWrite,
616          maxDiskRateName: maxBytesWriteName,
617        },
618        bytesWriteRow
619      );
620      bytesWriteRow.canvasRestore(context, this.trace);
621    };
622  }
623
624  private initBytesWriteRow(
625    bytesWriteRow: TraceRow<DiskAbilityMonitorStruct>, // @ts-ignore
626    parent: TraceRow<unknown>,
627    maxList: unknown[]
628  ): void {
629    bytesWriteRow.rowParentId = key;
630    bytesWriteRow.rowHidden = !parent.expansion;
631    bytesWriteRow.rowId = diskIONameList[1];
632    bytesWriteRow.rowType = TraceRow.ROW_TYPE_DISK_ABILITY;
633    bytesWriteRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
634    bytesWriteRow.selectChangeHandler = this.trace.selectChangeHandler;
635    bytesWriteRow.style.height = '40px';
636    bytesWriteRow.style.width = '100%';
637    bytesWriteRow.setAttribute('children', '');
638    bytesWriteRow.name = `Disk ${diskIONameList[1]}`;
639    bytesWriteRow.supplierFrame = (): Promise<DiskAbilityMonitorStruct[]> =>
640      abilityBytesReadDataSender(bytesWriteRow, 'AbilityBytesWrittenData').then((res): DiskAbilityMonitorStruct[] => {
641        this.computeDur(res);
642        return res;
643      });
644    bytesWriteRow.focusHandler = (ev): void => {
645      this.trace?.displayTip(
646        bytesWriteRow,
647        DiskAbilityMonitorStruct.hoverDiskAbilityStruct,
648        `<span>${DiskAbilityMonitorStruct.hoverDiskAbilityStruct?.value || '0'} KB/S</span>`
649      );
650    };
651    bytesWriteRow.findHoverStruct = (): void => {
652      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = bytesWriteRow.getHoverStruct();
653    };
654    this.bytesWriteThreadHandler(bytesWriteRow, maxList);
655  }
656
657  private initReadOspRow(
658    readOpsRow: TraceRow<DiskAbilityMonitorStruct>,
659    // @ts-ignore
660    parent: TraceRow<unknown>,
661    maxList: unknown[]
662  ): void {
663    // @ts-ignore
664    let maxReadOps = maxList[0].readOps;
665    let maxReadOpsName = this.diskIOMath(maxReadOps);
666    readOpsRow.rowParentId = key;
667    readOpsRow.rowHidden = !parent.expansion;
668    readOpsRow.rowId = diskIONameList[2];
669    readOpsRow.rowType = TraceRow.ROW_TYPE_DISK_ABILITY;
670    readOpsRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
671    readOpsRow.selectChangeHandler = this.trace.selectChangeHandler;
672    readOpsRow.style.height = '40px';
673    readOpsRow.style.width = '100%';
674    readOpsRow.setAttribute('children', '');
675    readOpsRow.name = `Disk ${diskIONameList[2]}`;
676    readOpsRow.supplierFrame = (): Promise<DiskAbilityMonitorStruct[]> =>
677      abilityBytesReadDataSender(readOpsRow, 'AbilityReadOpsData').then((res): DiskAbilityMonitorStruct[] => {
678        this.computeDur(res);
679        return res;
680      });
681    readOpsRow.focusHandler = (ev): void => {
682      this.trace?.displayTip(
683        readOpsRow,
684        DiskAbilityMonitorStruct.hoverDiskAbilityStruct,
685        `<span>${DiskAbilityMonitorStruct.hoverDiskAbilityStruct?.value || '0'} KB/S</span>`
686      );
687    };
688    readOpsRow.findHoverStruct = (): void => {
689      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = readOpsRow.getHoverStruct();
690    };
691    readOpsRow.onThreadHandler = (useCache): void => {
692      let context: CanvasRenderingContext2D;
693      if (readOpsRow.currentContext) {
694        context = readOpsRow.currentContext;
695      } else {
696        context = readOpsRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
697      }
698      readOpsRow.canvasSave(context);
699      (renders.monitorDiskIo as DiskIoAbilityRender).renderMainThread(
700        {
701          context: context,
702          useCache: useCache,
703          type: 'monitorDiskIo2',
704          maxDiskRate: maxReadOps,
705          maxDiskRateName: maxReadOpsName,
706        },
707        readOpsRow
708      );
709      readOpsRow.canvasRestore(context, this.trace);
710    };
711  }
712
713  private writeOspThreadHandler(writeOpsRow: TraceRow<DiskAbilityMonitorStruct>, maxList: unknown[]): void {
714    // @ts-ignore
715    let maxWriteOps = maxList[0].writeOps;
716    let maxWriteOpsName = this.diskIOMath(maxWriteOps);
717    writeOpsRow.onThreadHandler = (useCache): void => {
718      let context: CanvasRenderingContext2D;
719      if (writeOpsRow.currentContext) {
720        context = writeOpsRow.currentContext;
721      } else {
722        context = writeOpsRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
723      }
724      writeOpsRow.canvasSave(context);
725      (renders.monitorDiskIo as DiskIoAbilityRender).renderMainThread(
726        {
727          context: context,
728          useCache: useCache,
729          type: 'monitorDiskIo3',
730          maxDiskRate: maxWriteOps,
731          maxDiskRateName: maxWriteOpsName,
732        },
733        writeOpsRow
734      );
735      writeOpsRow.canvasRestore(context, this.trace);
736    };
737  }
738
739  private initWriteOspRow(
740    writeOpsRow: TraceRow<DiskAbilityMonitorStruct>, // @ts-ignore
741    parent: TraceRow<unknown>,
742    maxList: unknown[]
743  ): void {
744    writeOpsRow.rowParentId = key;
745    writeOpsRow.rowHidden = !parent.expansion;
746    writeOpsRow.rowId = diskIONameList[3];
747    writeOpsRow.rowType = TraceRow.ROW_TYPE_DISK_ABILITY;
748    writeOpsRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
749    writeOpsRow.selectChangeHandler = this.trace.selectChangeHandler;
750    writeOpsRow.style.height = '40px';
751    writeOpsRow.style.width = '100%';
752    writeOpsRow.setAttribute('children', '');
753    writeOpsRow.name = `Disk ${diskIONameList[3]}`;
754    writeOpsRow.supplierFrame = (): Promise<DiskAbilityMonitorStruct[]> =>
755      abilityBytesReadDataSender(writeOpsRow, 'AbilityWrittenOpsData').then((res): DiskAbilityMonitorStruct[] => {
756        this.computeDur(res);
757        return res;
758      });
759    writeOpsRow.focusHandler = (ev): void => {
760      this.trace?.displayTip(
761        writeOpsRow,
762        DiskAbilityMonitorStruct.hoverDiskAbilityStruct,
763        `<span>${DiskAbilityMonitorStruct.hoverDiskAbilityStruct?.value || '0'} KB/S</span>`
764      );
765    };
766    writeOpsRow.findHoverStruct = (): void => {
767      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = writeOpsRow.getHoverStruct();
768    };
769    this.writeOspThreadHandler(writeOpsRow, maxList);
770  }
771  private initDiskAbility = async (processRow: TraceRow<ProcessStruct>): Promise<void> => {
772    let time = new Date().getTime();
773    let maxList = await queryDiskIoMaxData();
774
775    let bytesReadTraceRow = TraceRow.skeleton<DiskAbilityMonitorStruct>();
776    this.initBytesReadRow(bytesReadTraceRow, processRow, maxList);
777    processRow.addChildTraceRow(bytesReadTraceRow);
778
779    let bytesWrittenTraceRow = TraceRow.skeleton<DiskAbilityMonitorStruct>();
780    this.initBytesWriteRow(bytesWrittenTraceRow, processRow, maxList);
781    processRow.addChildTraceRow(bytesWrittenTraceRow);
782
783    let readOpsTraceRow = TraceRow.skeleton<DiskAbilityMonitorStruct>();
784    this.initReadOspRow(readOpsTraceRow, processRow, maxList);
785    processRow.addChildTraceRow(readOpsTraceRow);
786
787    let writtenOpsTraceRow = TraceRow.skeleton<DiskAbilityMonitorStruct>();
788    this.initWriteOspRow(writtenOpsTraceRow, processRow, maxList);
789    processRow.addChildTraceRow(writtenOpsTraceRow);
790    let durTime = new Date().getTime() - time;
791    info('The time to load the Ability DiskIO is: ', durTime);
792  };
793
794  private bytesInRowThreadHandler(row: TraceRow<NetworkAbilityMonitorStruct>, maxList: unknown[]): void {
795    // @ts-ignore
796    let maxBytesIn = maxList[0].maxIn;
797    let maxInByteName = this.networkMath(maxBytesIn);
798    row.onThreadHandler = (useCache): void => {
799      let context: CanvasRenderingContext2D;
800      if (row.currentContext) {
801        context = row.currentContext;
802      } else {
803        context = row.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
804      }
805      row.canvasSave(context);
806      (renders.monitorNetwork as NetworkAbilityRender).renderMainThread(
807        {
808          context: context,
809          useCache: useCache,
810          type: 'monitorNetwork0',
811          maxNetworkRate: maxBytesIn,
812          maxNetworkRateName: maxInByteName,
813        },
814        row
815      );
816      row.canvasRestore(context, this.trace);
817    };
818  }
819
820  private initBytesInRow(
821    row: TraceRow<NetworkAbilityMonitorStruct>,
822    parent: TraceRow<ProcessStruct>,
823    maxList: unknown[]
824  ): void {
825    row.rowParentId = key;
826    row.rowHidden = !parent.expansion;
827    row.rowId = networkNameList[0];
828    row.rowType = TraceRow.ROW_TYPE_NETWORK_ABILITY;
829    row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
830    row.selectChangeHandler = this.trace.selectChangeHandler;
831    row.style.height = '40px';
832    row.style.width = '100%';
833    row.setAttribute('children', '');
834    row.name = `Network ${networkNameList[0]}`;
835    row.supplierFrame = (): Promise<NetworkAbilityMonitorStruct[]> =>
836      abilityBytesInTraceDataSender(row, 'AbilityBytesInTraceData').then((res): NetworkAbilityMonitorStruct[] => {
837        this.computeDur(res);
838        return res;
839      });
840    row.focusHandler = (ev): void => {
841      this.trace?.displayTip(
842        row,
843        NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct,
844        `<span>${Utils.getBinaryByteWithUnit(NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct?.value || 0)}</span>`
845      );
846    };
847    row.findHoverStruct = (): void => {
848      NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = row.getHoverStruct();
849    };
850    this.bytesInRowThreadHandler(row, maxList);
851  }
852  private bytesOutRowThreadHandler(row: TraceRow<NetworkAbilityMonitorStruct>, maxList: unknown[]): void {
853    // @ts-ignore
854    let maxBytesOut = maxList[0].maxOut;
855    let maxOutByteName = this.networkMath(maxBytesOut);
856    row.onThreadHandler = (useCache): void => {
857      let context: CanvasRenderingContext2D;
858      if (row.currentContext) {
859        context = row.currentContext;
860      } else {
861        context = row.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
862      }
863      row.canvasSave(context);
864      (renders.monitorNetwork as NetworkAbilityRender).renderMainThread(
865        {
866          context: context,
867          useCache: useCache,
868          type: 'monitorNetwork1',
869          maxNetworkRate: maxBytesOut,
870          maxNetworkRateName: maxOutByteName,
871        },
872        row
873      );
874      row.canvasRestore(context, this.trace);
875    };
876  }
877
878  private initBytesOutRow(
879    row: TraceRow<NetworkAbilityMonitorStruct>,
880    parent: TraceRow<ProcessStruct>,
881    maxList: unknown[]
882  ): void {
883    row.rowParentId = key;
884    row.rowHidden = !parent.expansion;
885    row.rowId = networkNameList[1];
886    row.rowType = TraceRow.ROW_TYPE_NETWORK_ABILITY;
887    row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
888    row.selectChangeHandler = this.trace.selectChangeHandler;
889    row.style.height = '40px';
890    row.style.width = '100%';
891    row.setAttribute('children', '');
892    row.name = `Network ${networkNameList[1]}`;
893    row.supplierFrame = (): Promise<NetworkAbilityMonitorStruct[]> =>
894      abilityBytesInTraceDataSender(row, 'AbilityBytesOutTraceData').then((res): NetworkAbilityMonitorStruct[] => {
895        this.computeDur(res);
896        return res;
897      });
898    row.focusHandler = (ev): void => {
899      this.trace?.displayTip(
900        row,
901        NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct,
902        `<span>${Utils.getBinaryByteWithUnit(NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct?.value || 0)}</span>`
903      );
904    };
905    row.findHoverStruct = (): void => {
906      NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = row.getHoverStruct();
907    };
908    this.bytesOutRowThreadHandler(row, maxList);
909  }
910
911  private packetInRowThreadHandler(row: TraceRow<NetworkAbilityMonitorStruct>, maxList: unknown[]): void {
912    // @ts-ignore
913    let maxPacketIn = maxList[0].maxPacketIn;
914    let maxInPacketName = this.networkMath(maxPacketIn);
915    row.onThreadHandler = (useCache): void => {
916      let context: CanvasRenderingContext2D;
917      if (row.currentContext) {
918        context = row.currentContext;
919      } else {
920        context = row.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
921      }
922      row.canvasSave(context);
923      (renders.monitorNetwork as NetworkAbilityRender).renderMainThread(
924        {
925          context: context,
926          useCache: useCache,
927          type: 'monitorNetwork-Packet2',
928          maxNetworkRate: maxPacketIn,
929          maxNetworkRateName: maxInPacketName,
930        },
931        row
932      );
933      row.canvasRestore(context, this.trace);
934    };
935  }
936
937  private initPacketInRow(
938    row: TraceRow<NetworkAbilityMonitorStruct>,
939    parent: TraceRow<ProcessStruct>,
940    maxList: unknown[]
941  ): void {
942    row.rowParentId = key;
943    row.rowHidden = !parent.expansion;
944    row.rowId = networkNameList[2];
945    row.rowType = TraceRow.ROW_TYPE_NETWORK_ABILITY;
946    row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
947    row.selectChangeHandler = this.trace.selectChangeHandler;
948    row.style.height = '40px';
949    row.style.width = '100%';
950    row.setAttribute('children', '');
951    row.name = `Network ${networkNameList[2]}`;
952    row.supplierFrame = (): Promise<NetworkAbilityMonitorStruct[]> =>
953      abilityBytesInTraceDataSender(row, 'AbilityPacketInTraceData').then((res): NetworkAbilityMonitorStruct[] => {
954        this.computeDur(res);
955        return res;
956      });
957    row.focusHandler = (ev): void => {
958      this.trace?.displayTip(
959        row,
960        NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct,
961        `<span>${Utils.getBinaryByteWithUnit(NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct?.value || 0)}</span>`
962      );
963    };
964    row.findHoverStruct = (): void => {
965      NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = row.getHoverStruct();
966    };
967    this.packetInRowThreadHandler(row, maxList);
968  }
969
970  private packetOutRowThreadHandler(row: TraceRow<NetworkAbilityMonitorStruct>, maxList: unknown[]): void {
971    // @ts-ignore
972    let maxPacketOut = maxList[0].maxPacketOut;
973    let maxOutPacketName = this.networkMath(maxPacketOut);
974    row.onThreadHandler = (useCache): void => {
975      let context: CanvasRenderingContext2D;
976      if (row.currentContext) {
977        context = row.currentContext;
978      } else {
979        context = row.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
980      }
981      row.canvasSave(context);
982      (renders.monitorNetwork as NetworkAbilityRender).renderMainThread(
983        {
984          context: context,
985          useCache: useCache,
986          type: 'monitorNetwork3',
987          maxNetworkRate: maxPacketOut,
988          maxNetworkRateName: maxOutPacketName,
989        },
990        row
991      );
992      row.canvasRestore(context, this.trace);
993    };
994  }
995
996  private initPacketOutRow(
997    row: TraceRow<NetworkAbilityMonitorStruct>,
998    parent: TraceRow<ProcessStruct>,
999    maxList: unknown[]
1000  ): void {
1001    row.rowParentId = key;
1002    row.rowHidden = !parent.expansion;
1003    row.rowId = networkNameList[3];
1004    row.rowType = TraceRow.ROW_TYPE_NETWORK_ABILITY;
1005    row.favoriteChangeHandler = this.trace.favoriteChangeHandler;
1006    row.selectChangeHandler = this.trace.selectChangeHandler;
1007    row.style.height = '40px';
1008    row.style.width = '100%';
1009    row.setAttribute('children', '');
1010    row.name = `Network ${networkNameList[3]}`;
1011    row.supplierFrame = (): Promise<NetworkAbilityMonitorStruct[]> =>
1012      abilityBytesInTraceDataSender(row, 'AbilityPacketsOutTraceData').then((res): NetworkAbilityMonitorStruct[] => {
1013        this.computeDur(res);
1014        return res;
1015      });
1016    row.focusHandler = (ev): void => {
1017      if (NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct) {
1018        this.trace?.displayTip(
1019          row,
1020          NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct,
1021          `<span>${Utils.getBinaryByteWithUnit(NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct!.value!)}</span>`
1022        );
1023      }
1024    };
1025    row.findHoverStruct = (): void => {
1026      NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = row.getHoverStruct();
1027    };
1028    this.packetOutRowThreadHandler(row, maxList);
1029  }
1030  private initNetworkAbility = async (processRow: TraceRow<ProcessStruct>): Promise<void> => {
1031    let time = new Date().getTime();
1032    let maxList = await queryNetWorkMaxData();
1033    let bytesInTraceRow = TraceRow.skeleton<NetworkAbilityMonitorStruct>();
1034    this.initBytesInRow(bytesInTraceRow, processRow, maxList);
1035    processRow.addChildTraceRow(bytesInTraceRow);
1036
1037    let bytesOutTraceRow = TraceRow.skeleton<NetworkAbilityMonitorStruct>();
1038    this.initBytesOutRow(bytesOutTraceRow, processRow, maxList);
1039    processRow.addChildTraceRow(bytesOutTraceRow);
1040    let packetInTraceRow = TraceRow.skeleton<NetworkAbilityMonitorStruct>();
1041    this.initPacketInRow(packetInTraceRow, processRow, maxList);
1042    processRow.addChildTraceRow(packetInTraceRow);
1043    let packetOutTraceRow = TraceRow.skeleton<NetworkAbilityMonitorStruct>();
1044    this.initPacketOutRow(packetOutTraceRow, processRow, maxList);
1045    processRow.addChildTraceRow(packetOutTraceRow);
1046    let durTime = new Date().getTime() - time;
1047    info('The time to load the Ability Network is: ', durTime);
1048  };
1049
1050  private async initPurgeableTotal(processRow: TraceRow<ProcessStruct>): Promise<void> {
1051    let snapshotDur = MemoryConfig.getInstance().snapshotDur;
1052    let totalTraceRow = this.initTraceRow(
1053      'System Purgeable Total',
1054      'Purgeable Total',
1055      TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY,
1056      processRow
1057    ); // @ts-ignore
1058    totalTraceRow.supplierFrame = (): Promise<unknown[]> =>
1059      new Promise<Array<unknown>>((resolve): void =>
1060        resolve(
1061          abilityPurgeableDataSender(totalTraceRow, snapshotDur, false).then((res: unknown[]) => {
1062            this.setName(res);
1063            return res;
1064          })
1065        )
1066      );
1067    processRow.addChildTraceRow(totalTraceRow);
1068  }
1069
1070  private async initPurgeablePin(processRow: TraceRow<ProcessStruct>): Promise<void> {
1071    let snapshotDur = MemoryConfig.getInstance().snapshotDur;
1072    let pinTraceRow = this.initTraceRow(
1073      'System Purgeable Pin',
1074      'Purgeable Pin',
1075      TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY,
1076      processRow
1077    ); // @ts-ignore
1078    pinTraceRow.supplierFrame = (): Promise<unknown[]> =>
1079      new Promise<Array<unknown>>((resolve): void =>
1080        resolve(
1081          abilityPurgeableDataSender(pinTraceRow, snapshotDur, true).then((res: unknown[]) => {
1082            this.setName(res);
1083            return res;
1084          })
1085        )
1086      );
1087    processRow.addChildTraceRow(pinTraceRow);
1088  }
1089
1090  /**
1091   * DMA
1092   * @param processRow
1093   */
1094  private initDmaAbility = async (processRow: TraceRow<ProcessStruct>): Promise<void> => {
1095    let snapshotDur = MemoryConfig.getInstance().snapshotDur;
1096    let dmaTraceRow = this.initTraceRow('abilityMonitorDma', 'DMA', TraceRow.ROW_TYPE_DMA_ABILITY, processRow); // @ts-ignore
1097    dmaTraceRow.supplierFrame = (): Promise<unknown[]> =>
1098      new Promise<Array<unknown>>((resolve): void =>
1099        resolve(
1100          abilityDmaDataSender(dmaTraceRow, snapshotDur).then((res: unknown[]) => {
1101            this.setName(res);
1102            return res;
1103          })
1104        )
1105      );
1106    processRow.addChildTraceRow(dmaTraceRow);
1107  };
1108
1109  /**
1110   * Skia Gpu Memory
1111   * @param processRow
1112   */
1113  private initGpuMemoryAbility = async (processRow: TraceRow<ProcessStruct>): Promise<void> => {
1114    let snapshotDur = MemoryConfig.getInstance().snapshotDur;
1115    let gpuMemoryTraceRow = this.initTraceRow(
1116      'abilityMonitorGpuMemory',
1117      'Skia Gpu Memory',
1118      TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY,
1119      processRow
1120    ); // @ts-ignore
1121    gpuMemoryTraceRow.supplierFrame = (): Promise<unknown[]> =>
1122      new Promise<Array<unknown>>((resolve): void =>
1123        resolve(
1124          abilityGpuMemoryDataSender(gpuMemoryTraceRow, snapshotDur).then((res: unknown[]) => {
1125            this.setName(res);
1126            return res;
1127          })
1128        )
1129      );
1130    processRow.addChildTraceRow(gpuMemoryTraceRow);
1131  };
1132
1133  private initTraceRow(
1134    rowId: string,
1135    rowName: string,
1136    type: string,
1137    processRow: TraceRow<ProcessStruct>
1138  ): TraceRow<SnapshotStruct> {
1139    let abilityMonitor = TraceRow.skeleton<SnapshotStruct>();
1140    abilityMonitor.rowParentId = key;
1141    abilityMonitor.rowHidden = !processRow.expansion;
1142    abilityMonitor.rowId = rowId;
1143    abilityMonitor.rowType = type;
1144    abilityMonitor.favoriteChangeHandler = this.trace.favoriteChangeHandler;
1145    abilityMonitor.selectChangeHandler = this.trace.selectChangeHandler;
1146    abilityMonitor.style.height = '40px';
1147    abilityMonitor.style.width = '100%';
1148    abilityMonitor.setAttribute('children', '');
1149    abilityMonitor.name = rowName;
1150    abilityMonitor.addTemplateTypes('Memory');
1151    abilityMonitor.focusHandler = (): void => {
1152      this.showTip(abilityMonitor);
1153    };
1154    abilityMonitor.findHoverStruct = (): void => {
1155      SnapshotStruct.hoverSnapshotStruct = abilityMonitor.getHoverStruct();
1156    };
1157    abilityMonitor.onThreadHandler = (useCache): void => {
1158      let context: CanvasRenderingContext2D;
1159      if (abilityMonitor.currentContext) {
1160        context = abilityMonitor.currentContext;
1161      } else {
1162        context = abilityMonitor.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
1163      }
1164      abilityMonitor.canvasSave(context);
1165      (renders.snapshot as SnapshotRender).renderMainThread(
1166        {
1167          context: context,
1168          useCache: useCache,
1169          type: 'snapshot',
1170        },
1171        abilityMonitor
1172      );
1173      abilityMonitor.canvasRestore(context, this.trace);
1174    };
1175    return abilityMonitor;
1176  }
1177
1178  private showTip(traceRow: TraceRow<SnapshotStruct>): void {
1179    this.trace?.displayTip(
1180      traceRow,
1181      SnapshotStruct.hoverSnapshotStruct,
1182      `<span>Name: ${SnapshotStruct.hoverSnapshotStruct?.name || ''}</span>
1183      <span>Size: ${Utils.getBinaryByteWithUnit(SnapshotStruct.hoverSnapshotStruct?.value || 0)}</span>`
1184    );
1185  }
1186
1187  private setName(data: Array<unknown>): void {
1188    if (data.length > 0) {
1189      data.forEach((item, index) => {
1190        // @ts-ignore
1191        item.name = `SnapShot ${index}`;
1192      });
1193    }
1194  }
1195
1196  private computeDur(list: Array<unknown>): void {
1197    let endNS = TraceRow.range?.endNS || 0;
1198    list.forEach((it, i) => {
1199      if (i === list.length - 1) {
1200        // @ts-ignore
1201        it.dur = (endNS || 0) - (it.startNS || 0);
1202      } else {
1203        // @ts-ignore
1204        it.dur = (list[i + 1].startNS || 0) - (it.startNS || 0);
1205      }
1206    });
1207  }
1208}
1209