1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace';
16fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow';
17fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker';
18fb726d48Sopenharmony_ciimport { type EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU';
19fb726d48Sopenharmony_ciimport { type HeapTimelineRender, HeapTimelineStruct } from '../../database/ui-worker/ProcedureWorkerHeapTimeline';
20fb726d48Sopenharmony_ciimport { HeapDataInterface, type ParseListener } from '../../../js-heap/HeapDataInterface';
21fb726d48Sopenharmony_ciimport { LoadDatabase } from '../../../js-heap/LoadDatabase';
22fb726d48Sopenharmony_ciimport { type FileInfo } from '../../../js-heap/model/UiStruct';
23fb726d48Sopenharmony_ciimport { type HeapSnapshotRender, HeapSnapshotStruct } from '../../database/ui-worker/ProcedureWorkerHeapSnapshot';
24fb726d48Sopenharmony_ciimport { Utils } from '../trace/base/Utils';
25fb726d48Sopenharmony_ciimport { type JsCpuProfilerChartFrame } from '../../bean/JsStruct';
26fb726d48Sopenharmony_ciimport { type JsCpuProfilerRender, JsCpuProfilerStruct } from '../../database/ui-worker/ProcedureWorkerCpuProfiler';
27fb726d48Sopenharmony_ciimport { ns2s } from '../../database/ui-worker/ProcedureWorkerCommon';
28fb726d48Sopenharmony_ciimport { cpuProfilerDataSender } from '../../database/data-trafic/ArkTsSender';
29fb726d48Sopenharmony_ciimport { queryJsCpuProfilerConfig, queryJsCpuProfilerData } from '../../database/sql/Cpu.sql';
30fb726d48Sopenharmony_ciimport { queryJsMemoryData } from '../../database/sql/Memory.sql';
31fb726d48Sopenharmony_ciimport { type HeapSample } from '../../../js-heap/model/DatabaseStruct';
32fb726d48Sopenharmony_ciimport { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil';
33fb726d48Sopenharmony_ci
34fb726d48Sopenharmony_ciconst TYPE_SNAPSHOT = 0;
35fb726d48Sopenharmony_ciconst TYPE_TIMELINE = 1;
36fb726d48Sopenharmony_ciconst LAMBDA_FUNCTION_NAME = '(anonymous)';
37fb726d48Sopenharmony_ciexport class SpArkTsChart implements ParseListener {
38fb726d48Sopenharmony_ci  private trace: SpSystemTrace; // @ts-ignore
39fb726d48Sopenharmony_ci  private folderRow: TraceRow<unknown> | undefined;
40fb726d48Sopenharmony_ci  private jsCpuProfilerRow: TraceRow<JsCpuProfilerStruct> | undefined;
41fb726d48Sopenharmony_ci  private heapTimelineRow: TraceRow<HeapTimelineStruct> | undefined;
42fb726d48Sopenharmony_ci  private heapSnapshotRow: TraceRow<HeapSnapshotStruct> | undefined;
43fb726d48Sopenharmony_ci  private loadJsDatabase: LoadDatabase;
44fb726d48Sopenharmony_ci  private allCombineDataMap = new Map<number, JsCpuProfilerChartFrame>();
45fb726d48Sopenharmony_ci  private process: string = '';
46fb726d48Sopenharmony_ci
47fb726d48Sopenharmony_ci  constructor(trace: SpSystemTrace) {
48fb726d48Sopenharmony_ci    this.trace = trace;
49fb726d48Sopenharmony_ci    this.loadJsDatabase = LoadDatabase.getInstance();
50fb726d48Sopenharmony_ci  }
51fb726d48Sopenharmony_ci
52fb726d48Sopenharmony_ci  public get chartFrameMap(): Map<number, JsCpuProfilerChartFrame> {
53fb726d48Sopenharmony_ci    return this.allCombineDataMap;
54fb726d48Sopenharmony_ci  }
55fb726d48Sopenharmony_ci
56fb726d48Sopenharmony_ci  private cpuProfilerSupplierFrame(): void {
57fb726d48Sopenharmony_ci    // @ts-ignore
58fb726d48Sopenharmony_ci    this.jsCpuProfilerRow!.supplierFrame = (): Promise<Array<unknown>> => {
59fb726d48Sopenharmony_ci      return cpuProfilerDataSender(this.jsCpuProfilerRow!).then((res: unknown) => {
60fb726d48Sopenharmony_ci        // @ts-ignore
61fb726d48Sopenharmony_ci        let maxHeight = res.maxDepth * 20;
62fb726d48Sopenharmony_ci        this.jsCpuProfilerRow!.style.height = `${maxHeight}px`; // @ts-ignore
63fb726d48Sopenharmony_ci        if (res.dataList.length > 0) {
64fb726d48Sopenharmony_ci          this.allCombineDataMap = new Map<number, JsCpuProfilerChartFrame>(); // @ts-ignore
65fb726d48Sopenharmony_ci          for (let data of res.dataList) {
66fb726d48Sopenharmony_ci            this.allCombineDataMap.set(data.id, data);
67fb726d48Sopenharmony_ci            SpSystemTrace.jsProfilerMap.set(data.id, data);
68fb726d48Sopenharmony_ci          } // @ts-ignore
69fb726d48Sopenharmony_ci          res.dataList.forEach((data: unknown) => {
70fb726d48Sopenharmony_ci            // @ts-ignore
71fb726d48Sopenharmony_ci            data.children = []; // @ts-ignore
72fb726d48Sopenharmony_ci            if (data.childrenIds.length > 0) {
73fb726d48Sopenharmony_ci              // @ts-ignore
74fb726d48Sopenharmony_ci              for (let id of data.childrenIds) {
75fb726d48Sopenharmony_ci                let child = SpSystemTrace.jsProfilerMap.get(Number(id)); // @ts-ignore
76fb726d48Sopenharmony_ci                data.children.push(child);
77fb726d48Sopenharmony_ci              }
78fb726d48Sopenharmony_ci            } // @ts-ignore
79fb726d48Sopenharmony_ci            data.name = SpSystemTrace.DATA_DICT.get(data.nameId) || LAMBDA_FUNCTION_NAME; // @ts-ignore
80fb726d48Sopenharmony_ci            data.url = SpSystemTrace.DATA_DICT.get(data.urlId) || 'unknown'; // @ts-ignore
81fb726d48Sopenharmony_ci            if (data.url && data.url !== 'unknown') {
82fb726d48Sopenharmony_ci              // @ts-ignore
83fb726d48Sopenharmony_ci              let dirs = data.url.split('/'); // @ts-ignore
84fb726d48Sopenharmony_ci              data.scriptName = dirs.pop() || '';
85fb726d48Sopenharmony_ci            }
86fb726d48Sopenharmony_ci          });
87fb726d48Sopenharmony_ci        } // @ts-ignore
88fb726d48Sopenharmony_ci        return res.dataList;
89fb726d48Sopenharmony_ci      });
90fb726d48Sopenharmony_ci    };
91fb726d48Sopenharmony_ci  }
92fb726d48Sopenharmony_ci
93fb726d48Sopenharmony_ci  private folderThreadHandler(): void {
94fb726d48Sopenharmony_ci    this.folderRow!.onThreadHandler = (useCache): void => {
95fb726d48Sopenharmony_ci      this.folderRow!.canvasSave(this.trace.canvasPanelCtx!);
96fb726d48Sopenharmony_ci      if (this.folderRow!.expansion) {
97fb726d48Sopenharmony_ci        // @ts-ignore
98fb726d48Sopenharmony_ci        this.trace.canvasPanelCtx?.clearRect(0, 0, this.folderRow!.frame.width, this.folderRow!.frame.height);
99fb726d48Sopenharmony_ci      } else {
100fb726d48Sopenharmony_ci        (renders.empty as EmptyRender).renderMainThread(
101fb726d48Sopenharmony_ci          {
102fb726d48Sopenharmony_ci            context: this.trace.canvasPanelCtx,
103fb726d48Sopenharmony_ci            useCache: useCache,
104fb726d48Sopenharmony_ci            type: '',
105fb726d48Sopenharmony_ci          },
106fb726d48Sopenharmony_ci          this.folderRow!
107fb726d48Sopenharmony_ci        );
108fb726d48Sopenharmony_ci      }
109fb726d48Sopenharmony_ci      this.folderRow!.canvasRestore(this.trace.canvasPanelCtx!, this.trace);
110fb726d48Sopenharmony_ci    };
111fb726d48Sopenharmony_ci  }
112fb726d48Sopenharmony_ci
113fb726d48Sopenharmony_ci  public async initFolder(): Promise<void> {
114fb726d48Sopenharmony_ci    let jsConfig = await queryJsCpuProfilerConfig();
115fb726d48Sopenharmony_ci    let jsCpu = await queryJsCpuProfilerData();
116fb726d48Sopenharmony_ci    let jsMemory = await queryJsMemoryData();
117fb726d48Sopenharmony_ci    if (jsMemory.length > 0 || jsCpu.length > 0) {
118fb726d48Sopenharmony_ci      this.folderRow = TraceRow.skeleton();
119fb726d48Sopenharmony_ci      //@ts-ignore
120fb726d48Sopenharmony_ci      this.process = jsConfig[0].pid;
121fb726d48Sopenharmony_ci      this.folderRow.rowId = this.process;
122fb726d48Sopenharmony_ci      this.folderRow.rowType = TraceRow.ROW_TYPE_ARK_TS;
123fb726d48Sopenharmony_ci      this.folderRow.style.height = '40px';
124fb726d48Sopenharmony_ci      this.folderRow.rowParentId = '';
125fb726d48Sopenharmony_ci      this.folderRow.folder = true;
126fb726d48Sopenharmony_ci      this.folderRow.name = `Ark Ts ${this.process}`;
127fb726d48Sopenharmony_ci      this.folderRow.addTemplateTypes('ArkTs');
128fb726d48Sopenharmony_ci      this.folderRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
129fb726d48Sopenharmony_ci      this.folderRow.selectChangeHandler = this.trace.selectChangeHandler;
130fb726d48Sopenharmony_ci      this.folderRow.supplierFrame = (): Promise<Array<unknown>> =>
131fb726d48Sopenharmony_ci        new Promise<Array<unknown>>((resolve) => resolve([]));
132fb726d48Sopenharmony_ci      this.folderThreadHandler();
133fb726d48Sopenharmony_ci      this.trace.rowsEL?.appendChild(this.folderRow); //@ts-ignore
134fb726d48Sopenharmony_ci      if (this.folderRow && jsConfig[0].type !== -1 && jsMemory.length > 0) {
135fb726d48Sopenharmony_ci        this.folderRow.addTemplateTypes('Memory');
136fb726d48Sopenharmony_ci        if (
137fb726d48Sopenharmony_ci          //@ts-ignore
138fb726d48Sopenharmony_ci          jsConfig[0].type === TYPE_SNAPSHOT
139fb726d48Sopenharmony_ci        ) {
140fb726d48Sopenharmony_ci          // snapshot
141fb726d48Sopenharmony_ci          await this.initSnapshotChart();
142fb726d48Sopenharmony_ci        } else if (
143fb726d48Sopenharmony_ci          //@ts-ignore
144fb726d48Sopenharmony_ci          jsConfig[0].type === TYPE_TIMELINE
145fb726d48Sopenharmony_ci        ) {
146fb726d48Sopenharmony_ci          // timeline
147fb726d48Sopenharmony_ci          await this.initTimelineChart();
148fb726d48Sopenharmony_ci        }
149fb726d48Sopenharmony_ci      }
150fb726d48Sopenharmony_ci      //@ts-ignore
151fb726d48Sopenharmony_ci      if (this.folderRow && jsConfig[0].enableCpuProfiler === 1 && jsCpu.length > 0) {
152fb726d48Sopenharmony_ci        await this.initJsCpuChart();
153fb726d48Sopenharmony_ci      }
154fb726d48Sopenharmony_ci      if ((this.heapSnapshotRow || this.heapTimelineRow) && jsMemory.length > 0) {
155fb726d48Sopenharmony_ci        await this.loadJsDatabase.loadDatabase(this);
156fb726d48Sopenharmony_ci      }
157fb726d48Sopenharmony_ci      if (this.jsCpuProfilerRow && jsCpu.length > 0) {
158fb726d48Sopenharmony_ci        this.cpuProfilerSupplierFrame();
159fb726d48Sopenharmony_ci      }
160fb726d48Sopenharmony_ci      // 统计arkTs插件
161fb726d48Sopenharmony_ci      let requsetBody = {
162fb726d48Sopenharmony_ci        eventData:{
163fb726d48Sopenharmony_ci          plugin:['arkts-plugin']
164fb726d48Sopenharmony_ci        }
165fb726d48Sopenharmony_ci      };
166fb726d48Sopenharmony_ci      SpStatisticsHttpUtil.recordPluginUsage(requsetBody);
167fb726d48Sopenharmony_ci    }
168fb726d48Sopenharmony_ci  }
169fb726d48Sopenharmony_ci
170fb726d48Sopenharmony_ci  private async initTimelineChart(): Promise<void> {
171fb726d48Sopenharmony_ci    this.heapTimelineRow = TraceRow.skeleton<HeapTimelineStruct>();
172fb726d48Sopenharmony_ci    this.heapTimelineRow.rowParentId = this.process;
173fb726d48Sopenharmony_ci    this.heapTimelineRow.rowHidden = !this.folderRow!.expansion;
174fb726d48Sopenharmony_ci    this.heapTimelineRow.style.height = '40px';
175fb726d48Sopenharmony_ci    this.heapTimelineRow.name = 'Heaptimeline';
176fb726d48Sopenharmony_ci    this.heapTimelineRow.folder = false;
177fb726d48Sopenharmony_ci    this.heapTimelineRow.rowType = TraceRow.ROW_TYPE_HEAP_TIMELINE;
178fb726d48Sopenharmony_ci    this.heapTimelineRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
179fb726d48Sopenharmony_ci    this.heapTimelineRow.selectChangeHandler = this.trace.selectChangeHandler;
180fb726d48Sopenharmony_ci    this.heapTimelineRow.setAttribute('children', '');
181fb726d48Sopenharmony_ci    this.heapTimelineRow!.focusHandler = (): void => {
182fb726d48Sopenharmony_ci      this.trace?.displayTip(
183fb726d48Sopenharmony_ci        this.heapTimelineRow!,
184fb726d48Sopenharmony_ci        HeapTimelineStruct.hoverHeapTimelineStruct,
185fb726d48Sopenharmony_ci        `<span>Size: ${Utils.getBinaryByteWithUnit(HeapTimelineStruct.hoverHeapTimelineStruct?.size || 0)}</span>`
186fb726d48Sopenharmony_ci      );
187fb726d48Sopenharmony_ci    };
188fb726d48Sopenharmony_ci    this.heapTimelineRow!.findHoverStruct = (): void => {
189fb726d48Sopenharmony_ci      HeapTimelineStruct.hoverHeapTimelineStruct = this.heapTimelineRow!.getHoverStruct();
190fb726d48Sopenharmony_ci    };
191fb726d48Sopenharmony_ci    this.folderRow!.addChildTraceRow(this.heapTimelineRow!);
192fb726d48Sopenharmony_ci  }
193fb726d48Sopenharmony_ci
194fb726d48Sopenharmony_ci  private async initSnapshotChart(): Promise<void> {
195fb726d48Sopenharmony_ci    this.heapSnapshotRow = TraceRow.skeleton<HeapSnapshotStruct>();
196fb726d48Sopenharmony_ci    this.heapSnapshotRow.rowParentId = this.process;
197fb726d48Sopenharmony_ci    this.heapSnapshotRow.rowHidden = !this.folderRow!.expansion;
198fb726d48Sopenharmony_ci    this.heapSnapshotRow.style.height = '40px';
199fb726d48Sopenharmony_ci    this.heapSnapshotRow.name = 'Heapsnapshot';
200fb726d48Sopenharmony_ci    this.heapSnapshotRow.rowId = 'heapsnapshot';
201fb726d48Sopenharmony_ci    this.heapSnapshotRow.folder = false;
202fb726d48Sopenharmony_ci
203fb726d48Sopenharmony_ci    this.heapSnapshotRow.rowType = TraceRow.ROW_TYPE_HEAP_SNAPSHOT;
204fb726d48Sopenharmony_ci    this.heapSnapshotRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
205fb726d48Sopenharmony_ci    this.heapSnapshotRow.selectChangeHandler = this.trace.selectChangeHandler;
206fb726d48Sopenharmony_ci    this.heapSnapshotRow.setAttribute('children', '');
207fb726d48Sopenharmony_ci    this.heapSnapshotRow!.focusHandler = (): void => {
208fb726d48Sopenharmony_ci      this.trace?.displayTip(
209fb726d48Sopenharmony_ci        this.heapSnapshotRow!,
210fb726d48Sopenharmony_ci        HeapSnapshotStruct.hoverSnapshotStruct,
211fb726d48Sopenharmony_ci        `<span>Name: ${HeapSnapshotStruct.hoverSnapshotStruct?.name || ''}</span>
212fb726d48Sopenharmony_ci            <span>Size: ${Utils.getBinaryByteWithUnit(HeapSnapshotStruct.hoverSnapshotStruct?.size || 0)}</span>`
213fb726d48Sopenharmony_ci      );
214fb726d48Sopenharmony_ci    };
215fb726d48Sopenharmony_ci    this.heapSnapshotRow!.findHoverStruct = (): void => {
216fb726d48Sopenharmony_ci      HeapSnapshotStruct.hoverSnapshotStruct = this.heapSnapshotRow!.getHoverStruct();
217fb726d48Sopenharmony_ci    };
218fb726d48Sopenharmony_ci    this.folderRow!.addChildTraceRow(this.heapSnapshotRow);
219fb726d48Sopenharmony_ci  }
220fb726d48Sopenharmony_ci
221fb726d48Sopenharmony_ci  private heapLineThreadHandler(samples: HeapSample[]): void {
222fb726d48Sopenharmony_ci    this.heapTimelineRow!.onThreadHandler = (useCache): void => {
223fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D;
224fb726d48Sopenharmony_ci      if (this.heapTimelineRow?.currentContext) {
225fb726d48Sopenharmony_ci        context = this.heapTimelineRow!.currentContext;
226fb726d48Sopenharmony_ci      } else {
227fb726d48Sopenharmony_ci        context = this.heapTimelineRow!.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
228fb726d48Sopenharmony_ci      }
229fb726d48Sopenharmony_ci      this.heapTimelineRow!.canvasSave(context);
230fb726d48Sopenharmony_ci      (renders['heap-timeline'] as HeapTimelineRender).renderMainThread(
231fb726d48Sopenharmony_ci        {
232fb726d48Sopenharmony_ci          context: context,
233fb726d48Sopenharmony_ci          useCache: useCache,
234fb726d48Sopenharmony_ci          type: 'heap-timeline',
235fb726d48Sopenharmony_ci          samples: samples,
236fb726d48Sopenharmony_ci        },
237fb726d48Sopenharmony_ci        this.heapTimelineRow!
238fb726d48Sopenharmony_ci      );
239fb726d48Sopenharmony_ci      this.heapTimelineRow!.canvasRestore(context, this.trace);
240fb726d48Sopenharmony_ci    };
241fb726d48Sopenharmony_ci  }
242fb726d48Sopenharmony_ci
243fb726d48Sopenharmony_ci  private heapSnapshotThreadHandler(): void {
244fb726d48Sopenharmony_ci    this.heapSnapshotRow!.onThreadHandler = (useCache): void => {
245fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D;
246fb726d48Sopenharmony_ci      if (this.heapSnapshotRow?.currentContext) {
247fb726d48Sopenharmony_ci        context = this.heapSnapshotRow!.currentContext;
248fb726d48Sopenharmony_ci      } else {
249fb726d48Sopenharmony_ci        context = this.heapSnapshotRow!.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
250fb726d48Sopenharmony_ci      }
251fb726d48Sopenharmony_ci      this.heapSnapshotRow!.canvasSave(context);
252fb726d48Sopenharmony_ci      (renders['heap-snapshot'] as HeapSnapshotRender).renderMainThread(
253fb726d48Sopenharmony_ci        {
254fb726d48Sopenharmony_ci          context: context,
255fb726d48Sopenharmony_ci          useCache: useCache,
256fb726d48Sopenharmony_ci          type: 'heap-snapshot',
257fb726d48Sopenharmony_ci        },
258fb726d48Sopenharmony_ci        this.heapSnapshotRow!
259fb726d48Sopenharmony_ci      );
260fb726d48Sopenharmony_ci      this.heapSnapshotRow!.canvasRestore(context, this.trace);
261fb726d48Sopenharmony_ci    };
262fb726d48Sopenharmony_ci  }
263fb726d48Sopenharmony_ci
264fb726d48Sopenharmony_ci  public async parseDone(fileModule: Array<FileInfo>): Promise<void> {
265fb726d48Sopenharmony_ci    if (fileModule.length > 0) {
266fb726d48Sopenharmony_ci      let heapFile = HeapDataInterface.getInstance().getFileStructs();
267fb726d48Sopenharmony_ci      let file = heapFile[0];
268fb726d48Sopenharmony_ci      this.trace.snapshotFile = file;
269fb726d48Sopenharmony_ci      if (file.type === TYPE_TIMELINE) {
270fb726d48Sopenharmony_ci        let samples = HeapDataInterface.getInstance().getSamples(file.id);
271fb726d48Sopenharmony_ci        this.heapTimelineRow!.rowId = `heaptimeline${file.id}`; // @ts-ignore
272fb726d48Sopenharmony_ci        this.heapTimelineRow!.supplierFrame = (): Promise<unknown> =>
273fb726d48Sopenharmony_ci          new Promise<unknown>((resolve) => resolve(samples));
274fb726d48Sopenharmony_ci        this.heapLineThreadHandler(samples);
275fb726d48Sopenharmony_ci      } else if (file.type === TYPE_SNAPSHOT) {
276fb726d48Sopenharmony_ci        // @ts-ignore
277fb726d48Sopenharmony_ci        this.heapSnapshotRow!.supplierFrame = (): Promise<Array<unknown>> =>
278fb726d48Sopenharmony_ci          new Promise<Array<unknown>>((resolve) => resolve(heapFile));
279fb726d48Sopenharmony_ci        this.heapSnapshotThreadHandler();
280fb726d48Sopenharmony_ci      }
281fb726d48Sopenharmony_ci    }
282fb726d48Sopenharmony_ci  }
283fb726d48Sopenharmony_ci
284fb726d48Sopenharmony_ci  private initJsCpuChart = async (): Promise<void> => {
285fb726d48Sopenharmony_ci    this.jsCpuProfilerRow = TraceRow.skeleton<JsCpuProfilerStruct>();
286fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.rowParentId = this.process;
287fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.rowHidden = !this.folderRow!.expansion;
288fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.name = 'CpuProfiler';
289fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.rowId = 'JsCpuProfiler';
290fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.folder = false;
291fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.rowType = TraceRow.ROW_TYPE_JS_CPU_PROFILER;
292fb726d48Sopenharmony_ci    this.jsCpuProfilerRow!.style.height = '40px';
293fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
294fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.selectChangeHandler = this.trace.selectChangeHandler;
295fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.setAttribute('children', '');
296fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.focusHandler = (): void => {
297fb726d48Sopenharmony_ci      this.trace?.displayTip(
298fb726d48Sopenharmony_ci        this.jsCpuProfilerRow!,
299fb726d48Sopenharmony_ci        JsCpuProfilerStruct.hoverJsCpuProfilerStruct,
300fb726d48Sopenharmony_ci        `<span style='font-weight: bold;'>Name: </span>
301fb726d48Sopenharmony_ci        <span>${JsCpuProfilerStruct.hoverJsCpuProfilerStruct?.name || ''}</span><br>
302fb726d48Sopenharmony_ci        <span style='font-weight: bold;'>Self Time: </span>
303fb726d48Sopenharmony_ci        <span>${ns2s(JsCpuProfilerStruct.hoverJsCpuProfilerStruct?.selfTime || 0)}</span><br>
304fb726d48Sopenharmony_ci        <span style='font-weight: bold;'>Total Time: </span>
305fb726d48Sopenharmony_ci        <span>${ns2s(JsCpuProfilerStruct.hoverJsCpuProfilerStruct?.totalTime || 0)}</span><br>
306fb726d48Sopenharmony_ci        <span style='font-weight: bold;'>Url: </span>
307fb726d48Sopenharmony_ci        <span>${JsCpuProfilerStruct.hoverJsCpuProfilerStruct?.url || 0}</span>`
308fb726d48Sopenharmony_ci      );
309fb726d48Sopenharmony_ci    };
310fb726d48Sopenharmony_ci    this.jsCpuProfilerRow!.findHoverStruct = (): void => {
311fb726d48Sopenharmony_ci      JsCpuProfilerStruct.hoverJsCpuProfilerStruct = this.jsCpuProfilerRow!.getHoverStruct();
312fb726d48Sopenharmony_ci    };
313fb726d48Sopenharmony_ci    this.jsCpuProfilerRow.onThreadHandler = (useCache): void => {
314fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D;
315fb726d48Sopenharmony_ci      if (this.jsCpuProfilerRow?.currentContext) {
316fb726d48Sopenharmony_ci        context = this.jsCpuProfilerRow!.currentContext;
317fb726d48Sopenharmony_ci      } else {
318fb726d48Sopenharmony_ci        context = this.jsCpuProfilerRow!.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
319fb726d48Sopenharmony_ci      }
320fb726d48Sopenharmony_ci      this.jsCpuProfilerRow!.canvasSave(context);
321fb726d48Sopenharmony_ci      (renders['js-cpu-profiler'] as JsCpuProfilerRender).renderMainThread(
322fb726d48Sopenharmony_ci        {
323fb726d48Sopenharmony_ci          context: context,
324fb726d48Sopenharmony_ci          useCache: useCache,
325fb726d48Sopenharmony_ci          type: 'js-cpu-profiler',
326fb726d48Sopenharmony_ci        },
327fb726d48Sopenharmony_ci        this.jsCpuProfilerRow!
328fb726d48Sopenharmony_ci      );
329fb726d48Sopenharmony_ci      this.jsCpuProfilerRow!.canvasRestore(context, this.trace);
330fb726d48Sopenharmony_ci    };
331fb726d48Sopenharmony_ci    this.folderRow!.addChildTraceRow(this.jsCpuProfilerRow);
332fb726d48Sopenharmony_ci  };
333fb726d48Sopenharmony_ci}
334