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