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 16 17import {BaseStruct} from "./BaseStruct.js"; 18import {Rect} from "../component/trace/timer-shaft/Rect.js"; 19import {ColorUtils} from "../component/trace/base/ColorUtils.js"; 20 21export class FuncStruct extends BaseStruct { 22 static hoverFuncStruct: FuncStruct | undefined; 23 static selectFuncStruct: FuncStruct | undefined; 24 argsetid: number | undefined 25 depth: number | undefined 26 dur: number | undefined 27 funName: string | undefined 28 id: number | undefined 29 is_main_thread: number | undefined 30 parent_id: number | undefined 31 startTs: number | undefined 32 threadName: string | undefined 33 tid: number | undefined 34 identify:number |undefined 35 track_id: number | undefined 36 37 static draw(ctx: CanvasRenderingContext2D, data: FuncStruct) { 38 if (data.frame) { 39 if (data.dur == undefined || data.dur == null || data.dur == 0 || FuncStruct.isBinder(data)) { 40 } else { 41 let width = data.frame.width || 0; 42 ctx.fillStyle = ColorUtils.FUNC_COLOR[data.depth || 0 % ColorUtils.FUNC_COLOR.length] 43 let miniHeight = 20 44 ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, miniHeight - padding * 2) 45 ctx.fillStyle = "#fff" 46 FuncStruct.drawString(ctx, data.funName || '', 5, data.frame) 47 if (FuncStruct.isSelected(data)) { 48 ctx.strokeStyle = "#000" 49 ctx.lineWidth = 1 50 ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, miniHeight - padding * 2) 51 } 52 } 53 } 54 } 55 56 static drawString(ctx: CanvasRenderingContext2D, str: string, textPadding: number, frame: Rect) { 57 let textMetrics = ctx.measureText(str); 58 let charWidth = Math.round(textMetrics.width / str.length) 59 if (textMetrics.width < frame.width - textPadding * 2) { 60 let x2 = Math.floor(frame.width / 2 - textMetrics.width / 2 + frame.x + textPadding) 61 ctx.fillText(str, x2, Math.floor(frame.y + frame.height / 2 + 2), frame.width - textPadding * 2) 62 return; 63 } 64 if (frame.width - textPadding * 2 > charWidth * 4) { 65 let chatNum = (frame.width - textPadding * 2) / charWidth; 66 let x1 = frame.x + textPadding 67 ctx.fillText(str.substring(0, chatNum - 4) + '...', x1, Math.floor(frame.y + frame.height / 2 + 2), frame.width - textPadding * 2) 68 return; 69 } 70 } 71 72 static isSelected(data: FuncStruct): boolean { 73 return (FuncStruct.selectFuncStruct != undefined && 74 FuncStruct.selectFuncStruct.startTs == data.startTs && 75 FuncStruct.selectFuncStruct.dur == data.dur && 76 FuncStruct.selectFuncStruct.funName == data.funName) 77 } 78 79 static isBinder(data: FuncStruct): boolean { 80 if (data.funName != null && 81 ( 82 data.funName.toLowerCase().startsWith("binder transaction") 83 || data.funName.toLowerCase().startsWith("binder async") 84 || data.funName.toLowerCase().startsWith("binder reply") 85 ) 86 ) { 87 return true; 88 } else { 89 return false; 90 } 91 } 92 93 static isBinderAsync(data: FuncStruct): boolean { 94 if (data.funName != null && 95 ( 96 data.funName.toLowerCase().includes("async") 97 ) 98 ) { 99 return true; 100 } else { 101 return false; 102 } 103 } 104} 105 106const padding = 1; 107