• 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 { SpHiPerf } from './SpHiPerf';
18import { SpCpuChart } from './SpCpuChart';
19import { SpFreqChart } from './SpFreqChart';
20import { SpFpsChart } from './SpFpsChart';
21import { info } from '../../../log/Log';
22import { SpNativeMemoryChart } from './SpNativeMemoryChart';
23import { SpAbilityMonitorChart } from './SpAbilityMonitorChart';
24import { SpProcessChart } from './SpProcessChart';
25import { perfDataQuery } from './PerfDataQuery';
26import { SpVirtualMemChart } from './SpVirtualMemChart';
27import { SpEBPFChart } from './SpEBPFChart';
28import { SpSdkChart } from './SpSdkChart';
29import { SpHiSysEnergyChart } from './SpHiSysEnergyChart';
30import { VmTrackerChart } from './SpVmTrackerChart';
31import { SpClockChart } from './SpClockChart';
32import { SpIrqChart } from './SpIrqChart';
33import { renders } from '../../database/ui-worker/ProcedureWorker';
34import { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU';
35import { TraceRow } from '../trace/base/TraceRow';
36import { SpFrameTimeChart } from './SpFrameTimeChart';
37import { Utils } from '../trace/base/Utils';
38import { SpArkTsChart } from './SpArkTsChart';
39import { MemoryConfig } from '../../bean/MemoryConfig';
40import { FlagsConfig } from '../SpFlags';
41import { SpLogChart } from './SpLogChart';
42import { SpHiSysEventChart } from './SpHiSysEventChart';
43import { SpAllAppStartupsChart } from './SpAllAppStartups';
44import { procedurePool } from '../../database/Procedure';
45import { SpSegmentationChart } from './SpSegmentationChart';
46import { SpPerfOutputDataChart } from './SpPerfOutputDataChart';
47import {
48  queryAppStartupProcessIds,
49  queryDataDICT,
50  queryThreadAndProcessName,
51} from '../../database/sql/ProcessThread.sql';
52import { queryTaskPoolCallStack, queryTotalTime, queryTraceRange } from '../../database/sql/SqlLite.sql';
53import { getCpuUtilizationRate } from '../../database/sql/Cpu.sql';
54import { queryMemoryConfig } from '../../database/sql/Memory.sql';
55import { SpLtpoChart } from './SpLTPO';
56import { SpBpftraceChart } from './SpBpftraceChart';
57import { sliceSender } from '../../database/data-trafic/SliceSender';
58
59export class SpChartManager {
60  static APP_STARTUP_PID_ARR: Array<number> = [];
61
62  private trace: SpSystemTrace;
63  public perf: SpHiPerf;
64  private cpu: SpCpuChart;
65  private freq: SpFreqChart;
66  private virtualMemChart: SpVirtualMemChart;
67  private fps: SpFpsChart;
68  private nativeMemory: SpNativeMemoryChart;
69  private abilityMonitor: SpAbilityMonitorChart;
70  private process: SpProcessChart;
71  private fileSystem: SpEBPFChart;
72  private sdkChart: SpSdkChart;
73  private hiSyseventChart: SpHiSysEnergyChart;
74  private smapsChart: VmTrackerChart;
75  private clockChart: SpClockChart;
76  private irqChart: SpIrqChart;
77  private spAllAppStartupsChart!: SpAllAppStartupsChart;
78  private SpLtpoChart!: SpLtpoChart;
79  frameTimeChart: SpFrameTimeChart;
80  public arkTsChart: SpArkTsChart;
81  private logChart: SpLogChart;
82  private spHiSysEvent: SpHiSysEventChart;
83  private spSegmentationChart: SpSegmentationChart;
84  private spBpftraceChart: SpBpftraceChart;
85  private tranceRange = { startTs: 0, endTs: 0 };
86  private spPerfOutputDataChart: SpPerfOutputDataChart;
87
88  constructor(trace: SpSystemTrace) {
89    this.trace = trace;
90    this.perf = new SpHiPerf(trace);
91    this.fileSystem = new SpEBPFChart(trace);
92    this.cpu = new SpCpuChart(trace);
93    this.freq = new SpFreqChart(trace);
94    this.virtualMemChart = new SpVirtualMemChart(trace);
95    this.fps = new SpFpsChart(trace);
96    this.nativeMemory = new SpNativeMemoryChart(trace);
97    this.abilityMonitor = new SpAbilityMonitorChart(trace);
98    this.process = new SpProcessChart(trace);
99    this.sdkChart = new SpSdkChart(trace);
100    this.hiSyseventChart = new SpHiSysEnergyChart(trace);
101    this.smapsChart = new VmTrackerChart(trace);
102    this.clockChart = new SpClockChart(trace);
103    this.irqChart = new SpIrqChart(trace);
104    this.frameTimeChart = new SpFrameTimeChart(trace);
105    this.arkTsChart = new SpArkTsChart(trace);
106    this.logChart = new SpLogChart(trace);
107    this.spHiSysEvent = new SpHiSysEventChart(trace);
108    this.spAllAppStartupsChart = new SpAllAppStartupsChart(trace);
109    this.SpLtpoChart = new SpLtpoChart(trace);
110    this.spSegmentationChart = new SpSegmentationChart(trace);
111    this.spBpftraceChart = new SpBpftraceChart(trace);
112    this.spPerfOutputDataChart = new SpPerfOutputDataChart(trace);
113  }
114  async initPreprocessData(progress: Function): Promise<void> {
115    progress('load data dict', 50);
116    SpSystemTrace.DATA_DICT.clear();
117    SpChartManager.APP_STARTUP_PID_ARR = [];
118    let dict = await queryDataDICT();
119    if (FlagsConfig.getFlagsConfigEnableStatus('AppStartup')) {
120      let appStartUpPids = await queryAppStartupProcessIds();
121      appStartUpPids.forEach((it) => SpChartManager.APP_STARTUP_PID_ARR.push(it.pid));
122    }
123    await this.initTraceConfig(); //@ts-ignore
124    dict.map((d) => SpSystemTrace.DATA_DICT.set(d.id, d.data));
125    await this.cacheDataDictToWorker();
126    SpSystemTrace.DATA_TASK_POOL_CALLSTACK.clear();
127    let taskPoolCallStack = await queryTaskPoolCallStack();
128    taskPoolCallStack.map((d) => SpSystemTrace.DATA_TASK_POOL_CALLSTACK.set(d.id, d));
129    progress('time range', 65);
130    await this.initTotalTime();
131    let ptArr = await queryThreadAndProcessName(); //@ts-ignore
132    this.handleProcessThread(ptArr);
133    info('initData timerShaftEL Data initialized');
134    const range = await queryTraceRange();
135    //@ts-ignore
136    this.tranceRange = range[0];
137  }
138
139  async initCpu(progress: Function): Promise<void> {
140    progress('cpu', 70);
141    let count = await sliceSender(); //@ts-ignore
142    await this.cpu.init(count.cpu);
143    info('initData cpu Data initialized');
144    if (FlagsConfig.getFlagsConfigEnableStatus('Bpftrace')) {
145      await this.spBpftraceChart.init(null);
146    }
147    if (FlagsConfig.getFlagsConfigEnableStatus('SchedulingAnalysis')) {
148      await this.cpu.initCpuIdle0Data(progress);
149      await this.cpu.initSchedulingPTData(progress);
150      await this.cpu.initSchedulingFreqData(progress);
151    }
152    info('initData ProcessThreadState Data initialized');
153    progress('cpu rate', 75);
154    await this.initCpuRate();
155    info('initData Cpu Rate Data initialized');
156    progress('cpu freq', 80);
157    await this.freq.init();
158    info('initData Cpu Freq Data initialized');
159  }
160
161  async init(progress: Function): Promise<void> {
162    info('initData data parse end ');
163    await this.initPreprocessData(progress);
164    await this.initCpu(progress);
165    await this.logChart.init();
166    await this.spHiSysEvent.init();
167    progress('Clock init', 82);
168    await this.clockChart.init();
169    progress('Irq init', 84);
170    await this.irqChart.init();
171    progress('SpSegmentationChart inin', 84.5);
172    await this.spSegmentationChart.init();
173    await this.virtualMemChart.init();
174    progress('fps', 85);
175    await this.fps.init();
176    progress('native memory', 87);
177    await this.nativeMemory.initChart();
178    progress('ability monitor', 88);
179    await this.abilityMonitor.init();
180    progress('hiSysevent', 88.2);
181    await this.hiSyseventChart.init();
182    progress('vm tracker', 88.4);
183    await this.smapsChart.init();
184    progress('sdk', 88.6);
185    await this.sdkChart.init();
186    progress('perf', 88.8);
187    await this.perf!.init();
188    await perfDataQuery.initPerfCache();
189    progress('file system', 89);
190    await this.fileSystem!.init();
191    progress('ark ts', 90);
192    await this.arkTsChart.initFolder();
193    await this.spAllAppStartupsChart.init();
194    await this.SpLtpoChart.init();
195    await this.frameTimeChart.init();
196    await this.spPerfOutputDataChart.init();
197    progress('process', 92);
198    await this.process.initAsyncFuncData(this.tranceRange);
199    await this.process.initDeliverInputEvent();
200    await this.process.init();
201    progress('display', 95);
202  }
203
204  async initSample(ev: File): Promise<void> {
205    await this.initSampleTime();
206    await this.spBpftraceChart.init(ev);
207  }
208
209  async importSoFileUpdate(): Promise<void> {
210    SpSystemTrace.DATA_DICT.clear();
211    let dict = await queryDataDICT(); //@ts-ignore
212    dict.map((d) => SpSystemTrace.DATA_DICT.set(d.id, d.data));
213    await this.cacheDataDictToWorker();
214    await perfDataQuery.initPerfCache();
215    await this.nativeMemory.initNativeMemory();
216    await this.fileSystem.initFileCallchain();
217    this.perf.resetAllChartData();
218  }
219
220  handleProcessThread(arr: { id: number; name: string; type: string }[]): void {
221    Utils.PROCESS_MAP.clear();
222    Utils.THREAD_MAP.clear();
223    for (let pt of arr) {
224      if (pt.type === 'p') {
225        Utils.PROCESS_MAP.set(pt.id, pt.name);
226      } else {
227        Utils.THREAD_MAP.set(pt.id, pt.name);
228      }
229    }
230  }
231
232  initTotalTime = async (): Promise<void> => {
233    let res = await queryTotalTime();
234    if (this.trace.timerShaftEL) {
235      let total = res[0].total;
236      let startNS = res[0].recordStartNS;
237      let endNS = res[0].recordEndNS;
238      if (total === 0 && startNS === endNS) {
239        total = 1;
240        endNS = startNS + 1;
241      }
242      this.trace.timerShaftEL.totalNS = total;
243      this.trace.timerShaftEL.getRangeRuler()!.drawMark = true;
244      this.trace.timerShaftEL.setRangeNS(0, total);
245      window.recordStartNS = startNS;
246      window.recordEndNS = endNS;
247      window.totalNS = total;
248      this.trace.timerShaftEL.loadComplete = true;
249    }
250  };
251
252  initSampleTime = async (): Promise<void> => {
253    if (this.trace.timerShaftEL) {
254      let total = 30_000_000_000;
255      let startNS = 0;
256      let endNS = 30_000_000_000;
257      this.trace.timerShaftEL.totalNS = total;
258      this.trace.timerShaftEL.getRangeRuler()!.drawMark = true;
259      this.trace.timerShaftEL.setRangeNS(0, total); // @ts-ignore
260      (window as unknown).recordStartNS = startNS; // @ts-ignore
261      (window as unknown).recordEndNS = endNS; // @ts-ignore
262      (window as unknown).totalNS = total;
263      this.trace.timerShaftEL.loadComplete = true;
264    }
265  };
266
267  initCpuRate = async (): Promise<void> => {
268    let rates = await getCpuUtilizationRate(0, this.trace.timerShaftEL?.totalNS || 0);
269    if (this.trace.timerShaftEL) {
270      this.trace.timerShaftEL.cpuUsage = rates;
271    }
272    info('Cpu UtilizationRate data size is: ', rates.length);
273  };
274
275  initTraceConfig = async (): Promise<void> => {
276    queryMemoryConfig().then((result) => {
277      if (result && result.length > 0) {
278        const config = result[0];
279        MemoryConfig.getInstance().updateConfig(config.pid, config.iPid, config.processName, config.interval);
280      }
281    });
282  };
283
284  async cacheDataDictToWorker(): Promise<void> {
285    return new Promise((resolve) => {
286      procedurePool.submitWithName(
287        'logic0',
288        'cache-data-dict',
289        { dataDict: SpSystemTrace.DATA_DICT },
290        undefined,
291        (res: unknown): void => {
292          resolve();
293        }
294      );
295    });
296  }
297}
298
299export const folderSupplier = (): unknown => {
300  return () => new Promise<Array<unknown>>((resolve) => resolve([]));
301}; // @ts-ignore
302export const folderThreadHandler = (row: TraceRow<unknown>, trace: SpSystemTrace) => {
303  return (useCache: boolean): void => {
304    row.canvasSave(trace.canvasPanelCtx!);
305    if (row.expansion) {
306      // @ts-ignore
307      trace.canvasPanelCtx?.clearRect(0, 0, row.frame.width, row.frame.height);
308    } else {
309      (renders.empty as EmptyRender).renderMainThread(
310        {
311          context: trace.canvasPanelCtx,
312          useCache: useCache,
313          type: '',
314        },
315        row
316      );
317    }
318    row.canvasRestore(trace.canvasPanelCtx!, trace);
319  };
320};
321
322export function rowThreadHandler<T>(
323  tag: string,
324  contextField: string,
325  arg: unknown, // @ts-ignore
326  row: TraceRow<unknown>,
327  trace: SpSystemTrace
328) {
329  return (useCache: boolean): void => {
330    let context: CanvasRenderingContext2D = getRowContext(row, trace);
331    row.canvasSave(context); // @ts-ignore
332    arg.useCache = useCache;
333    if (contextField) {
334      // @ts-ignore
335      arg[contextField] = context;
336    } // @ts-ignore
337    (renders[tag] as unknown).renderMainThread(arg, row);
338    row.canvasRestore(context, trace);
339  };
340}
341// @ts-ignore
342export const getRowContext = (row: TraceRow<unknown>, trace: SpSystemTrace): CanvasRenderingContext2D => {
343  if (row.currentContext) {
344    return row.currentContext;
345  } else {
346    return row.collect ? trace.canvasFavoritePanelCtx! : trace.canvasPanelCtx!;
347  }
348};
349