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 { BaseStruct, dataFilterHandler, drawLoadingFrame, drawString } from './ProcedureWorkerCommon'; 17import { TraceRow } from '../../component/trace/base/TraceRow'; 18import { ColorUtils } from '../../component/trace/base/ColorUtils'; 19import { SpSystemTrace } from '../../component/SpSystemTrace'; 20 21export class AppStartupRender { 22 renderMainThread( 23 appStartReq: { 24 useCache: boolean; 25 appStartupContext: CanvasRenderingContext2D; 26 type: string; 27 }, 28 appStartUpRow: TraceRow<AppStartupStruct> 29 ): void { 30 let list = appStartUpRow.dataList; 31 let appStartUpfilter = appStartUpRow.dataListCache; 32 dataFilterHandler(list, appStartUpfilter, { 33 startKey: 'startTs', 34 durKey: 'dur', 35 startNS: TraceRow.range?.startNS ?? 0, 36 endNS: TraceRow.range?.endNS ?? 0, 37 totalNS: TraceRow.range?.totalNS ?? 0, 38 frame: appStartUpRow.frame, 39 paddingTop: 5, 40 useCache: appStartReq.useCache || !(TraceRow.range?.refresh ?? false), 41 }); 42 drawLoadingFrame(appStartReq.appStartupContext, appStartUpRow.dataListCache, appStartUpRow); 43 appStartReq.appStartupContext.globalAlpha = 0.6; 44 let find = false; 45 let offset = 3; 46 for (let re of appStartUpfilter) { 47 AppStartupStruct.draw(appStartReq.appStartupContext, re); 48 if (appStartUpRow.isHover) { 49 if ( 50 re.frame && 51 appStartUpRow.hoverX >= re.frame.x - offset && 52 appStartUpRow.hoverX <= re.frame.x + re.frame.width + offset 53 ) { 54 AppStartupStruct.hoverStartupStruct = re; 55 find = true; 56 } 57 } 58 } 59 if (!find && appStartUpRow.isHover) { 60 AppStartupStruct.hoverStartupStruct = undefined; 61 } 62 } 63} 64 65const padding = 3; 66export function AppStartupStructOnClick( 67 clickRowType: string, 68 sp: SpSystemTrace, 69 scrollToFuncHandler: Function 70): Promise<unknown> { 71 return new Promise((resolve, reject) => { 72 if (clickRowType === TraceRow.ROW_TYPE_APP_STARTUP && AppStartupStruct.hoverStartupStruct) { 73 AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct; 74 sp.traceSheetEL?.displayStartupData( 75 AppStartupStruct.selectStartupStruct, 76 scrollToFuncHandler, 77 sp.currentRow!.dataListCache 78 ); 79 sp.timerShaftEL?.modifyFlagList(undefined); 80 reject(new Error()); 81 } else { 82 resolve(null); 83 } 84 }); 85} 86export class AppStartupStruct extends BaseStruct { 87 static hoverStartupStruct: AppStartupStruct | undefined; 88 static selectStartupStruct: AppStartupStruct | undefined; 89 static StartUpStep: string[] = [ 90 'ProcessTouchEvent', 91 'StartUIAbilityBySCB', 92 'LoadAbility', 93 'Application Launching', 94 'UI Ability Launching', 95 'UI Ability OnForeground', 96 'First Frame - APP Phase', 97 'First Frame - Render Phase', 98 ]; 99 startTs: number | undefined; 100 startName: number = 0; 101 dur: number | undefined; 102 value: string | undefined; 103 pid: number | undefined; 104 process: string | undefined; 105 tid: number | undefined; 106 itid: number | undefined; 107 endItid: number | undefined; 108 stepName: string | undefined; 109 StartSlice: string | undefined; 110 EndSlice: string | undefined; 111 112 static draw(ctx: CanvasRenderingContext2D, data: AppStartupStruct): void { 113 if (data.frame) { 114 ctx.globalAlpha = 1.0; 115 ctx.fillStyle = ColorUtils.colorForTid(data.startName!); 116 ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); 117 if (data.frame.width > 7) { 118 ctx.textBaseline = 'middle'; 119 ctx.lineWidth = 1; 120 if (data.stepName === undefined) { 121 data.stepName = `${AppStartupStruct.getStartupName(data.startName)} (${(data.dur! / 1000000).toFixed(2)}ms)`; 122 } 123 let textColor = 124 ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.stepName || '', 0, ColorUtils.FUNC_COLOR.length)]; 125 ctx.fillStyle = ColorUtils.funcTextColor(textColor); 126 drawString(ctx, data.stepName, 2, data.frame, data); 127 } 128 if (data === AppStartupStruct.selectStartupStruct) { 129 ctx.strokeStyle = '#232c5d'; 130 ctx.lineWidth = 2; 131 ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); 132 } 133 } 134 } 135 136 static getStartupName(step: number | undefined): string { 137 if (step === undefined || step < 0 || step > 7) { 138 return 'Unknown Start Step'; 139 } else { 140 return AppStartupStruct.StartUpStep[step]; 141 } 142 } 143} 144