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 { TraceRow } from '../trace/base/TraceRow'; 18import { renders } from '../../database/ui-worker/ProcedureWorker'; 19import { CpuFreqStruct } from '../../database/ui-worker/ProcedureWorkerFreq'; 20import { queryAppStartupProcessIds, queryProcessStartup, querySingleAppStartupsName } from '../../database/sql/ProcessThread.sql'; 21import { FlagsConfig } from '../SpFlags'; 22import { AllAppStartupStruct, AllAppStartupRender } from '../../database/ui-worker/ProcedureWorkerAllAppStartup'; 23 24export class SpAllAppStartupsChart { 25 private readonly trace: SpSystemTrace | undefined; 26 static APP_STARTUP_PID_ARR: Array<number> = []; 27 static jsonRow: TraceRow<CpuFreqStruct> | undefined; 28 static trace: SpSystemTrace; 29 static AllAppStartupsNameArr: any[] = []; 30 static allAppStartupsAva: number[] = []; 31 32 constructor(trace: SpSystemTrace) { 33 SpAllAppStartupsChart.trace = trace; 34 } 35 36 async init() { 37 SpAllAppStartupsChart.APP_STARTUP_PID_ARR = []; 38 let appStartUpPids = await queryAppStartupProcessIds(); 39 appStartUpPids.forEach((it) => SpAllAppStartupsChart.APP_STARTUP_PID_ARR.push(it.pid)); 40 SpAllAppStartupsChart.AllAppStartupsNameArr = []; 41 SpAllAppStartupsChart.allAppStartupsAva = []; 42 for (let i = 0; i < SpAllAppStartupsChart.APP_STARTUP_PID_ARR.length; i++) { 43 let tmpSingleApp: any[] = await queryProcessStartup(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); 44 if (tmpSingleApp.length == 8) { 45 let avilSingleName = await querySingleAppStartupsName(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); 46 SpAllAppStartupsChart.allAppStartupsAva.push(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]); 47 SpAllAppStartupsChart.AllAppStartupsNameArr.push(avilSingleName![0].name); 48 } 49 } 50 let loadAppStartup: boolean = FlagsConfig.getFlagsConfigEnableStatus('AppStartup'); 51 if (loadAppStartup && SpAllAppStartupsChart.allAppStartupsAva.length) await this.initFolder(); 52 } 53 54 async initFolder() { 55 let row: TraceRow<AllAppStartupStruct> = TraceRow.skeleton<AllAppStartupStruct>(); 56 row.setAttribute('hasStartup', 'true'); 57 row.rowId = `all-app-start-${SpAllAppStartupsChart.APP_STARTUP_PID_ARR![0]}`; 58 row.index = 0; 59 row.rowType = TraceRow.ROW_TYPE_ALL_APPSTARTUPS; 60 row.rowParentId = ''; 61 row.folder = false; 62 row.style.height = '40px'; 63 row.name = `All App Startups`; 64 row.selectChangeHandler = SpAllAppStartupsChart.trace.selectChangeHandler; 65 row.favoriteChangeHandler = SpAllAppStartupsChart.trace.favoriteChangeHandler; 66 row.supplier = async (): Promise<Array<AllAppStartupStruct>> => { 67 let sendRes: AllAppStartupStruct[] | PromiseLike<AllAppStartupStruct[]> = []; 68 for (let i = 0; i < SpAllAppStartupsChart.allAppStartupsAva.length; i++) { 69 let tmpResArr = await queryProcessStartup(SpAllAppStartupsChart.allAppStartupsAva[i]); 70 let maxStartTs: number | undefined = tmpResArr[0].startTs; 71 let minStartTs: number | undefined = tmpResArr[0].startTs; 72 let singleDur = tmpResArr[0].dur; 73 let endTs: number | undefined = tmpResArr[0].startTs; 74 if (tmpResArr.length > 1) { 75 for (let j = 0; j < tmpResArr.length; j++) { 76 if (Number(tmpResArr[j].startTs) > Number(maxStartTs)) { 77 maxStartTs = tmpResArr[j].startTs; 78 } else if (Number(tmpResArr[j].startTs) < Number(minStartTs)) { 79 minStartTs = tmpResArr[j].startTs; 80 } 81 } 82 tmpResArr.forEach((item) => { 83 if (item.startTs == maxStartTs) { 84 endTs = Number(item.startTs) + Number(item.dur); 85 singleDur = Number(endTs) - Number(minStartTs); 86 } 87 }); 88 } else if (tmpResArr.length === 1) { 89 minStartTs = tmpResArr[0].startTs; 90 singleDur = tmpResArr[0].dur; 91 } 92 sendRes.push({ 93 dur: singleDur, 94 startTs: minStartTs, 95 startName: undefined, 96 stepName: SpAllAppStartupsChart.AllAppStartupsNameArr[i], 97 translateY: undefined, 98 frame: undefined, 99 isHover: false, 100 }); 101 } 102 return sendRes; 103 }; 104 105 row.onThreadHandler = (useCache): void => { 106 let context: CanvasRenderingContext2D; 107 if (row.currentContext) { 108 context = row.currentContext; 109 } else { 110 context = row.collect 111 ? SpAllAppStartupsChart.trace.canvasFavoritePanelCtx! 112 : SpAllAppStartupsChart.trace.canvasPanelCtx!; 113 } 114 row.canvasSave(context); 115 (renders['all-app-start-up'] as AllAppStartupRender).renderMainThread( 116 { 117 appStartupContext: context, 118 useCache: useCache, 119 type: `app-startup ${row.rowId}`, 120 }, 121 row 122 ); 123 row.canvasRestore(context, this.trace); 124 }; 125 SpAllAppStartupsChart.trace.rowsEL?.appendChild(row); 126 } 127} 128