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