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