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 { ColorUtils } from "../../component/trace/base/ColorUtils.js"; 17import { 18 BaseStruct, 19 drawFlagLine, 20 drawLines, 21 drawLoading, 22 drawSelection, 23 PerfRender, 24 RequestMessage 25} from "./ProcedureWorkerCommon.js"; 26 27export class EnergyAnomalyRender extends PerfRender { 28 render(req: RequestMessage, list: Array<any>, filter: Array<any>,dataList2:Array<any>){ 29 if (req.lazyRefresh) { 30 anomaly(list, filter, req.startNS, req.endNS, req.totalNS, req.frame, req.params.appName, req.useCache || !req.range.refresh); 31 } else { 32 if (!req.useCache) { 33 anomaly(list, filter, req.startNS, req.endNS, req.totalNS, req.frame, req.params.appName, false); 34 } 35 } 36 if (req.canvas) { 37 req.context.clearRect(0, 0, req.canvas.width, req.canvas.height); 38 let arr = filter; 39 if (arr.length > 0 && !req.range.refresh && !req.useCache && req.lazyRefresh) { 40 drawLoading(req.context, req.startNS, req.endNS, req.totalNS, req.frame, arr[0].startNS, arr[arr.length - 1].startNS) 41 } 42 drawLines(req.context, req.xs, req.frame.height, req.lineColor) 43 req.context.stroke(); 44 req.context.beginPath(); 45 EnergyAnomalyStruct.hoverEnergyAnomalyStruct = undefined; 46 if (req.isHover) { 47 let offset = 3; 48 for (let re of filter) { 49 if (re.frame && req.hoverX >= re.frame.x - offset && req.hoverX <= re.frame.x + re.frame.width + offset) { 50 EnergyAnomalyStruct.hoverEnergyAnomalyStruct = re; 51 break; 52 } 53 } 54 } else { 55 EnergyAnomalyStruct.hoverEnergyAnomalyStruct = req.params.hoverStruct; 56 } 57 EnergyAnomalyStruct.selectEnergyAnomalyStruct = req.params.selectEnergyAnomalyStruct; 58 req.context.fillStyle = ColorUtils.FUNC_COLOR[0] 59 req.context.strokeStyle = ColorUtils.FUNC_COLOR[0]; 60 let path = new Path2D(); 61 for (let re of filter) { 62 EnergyAnomalyStruct.draw(req.context, path, re); 63 } 64 req.context.fillStyle = "#E64566"; 65 req.context.strokeStyle = "#E64566"; 66 req.context.fillRect(req.canvas.width - 290, 12, 8, 8); 67 req.context.globalAlpha = 1 68 req.context.fillStyle = "#333" 69 req.context.textBaseline = "middle" 70 req.context.fillText("System Abnormality", req.canvas.width - 225, 18) 71 req.context.stroke(path); 72 req.context.fillStyle = "#FFC880"; 73 req.context.strokeStyle = "#FFC880"; 74 req.context.fillRect(req.canvas.width - 145, 12, 8, 8); 75 req.context.globalAlpha = 1 76 req.context.fillStyle = "#333" 77 req.context.textBaseline = "middle" 78 req.context.fillText("Application Abnormality", req.canvas.width - 70, 18) 79 req.context.stroke(path); 80 drawSelection(req.context, req.params); 81 req.context.closePath(); 82 drawFlagLine(req.context, req.flagMoveInfo, req.flagSelectedInfo, req.startNS, req.endNS, req.totalNS, req.frame, req.slicesTime); 83 } 84 // @ts-ignore 85 self.postMessage({ 86 id: req.id, 87 type: req.type, 88 results: req.canvas ? undefined : filter, 89 hover: EnergyAnomalyStruct.hoverEnergyAnomalyStruct 90 }); 91 } 92} 93 94export function anomaly(arr: Array<any>, res: Array<any>, startNS: number, endNS: number, totalNS: number, frame: any, appName: string | undefined, use: boolean) { 95 if (use && res.length > 0 ) { 96 let pns = (endNS - startNS) / frame.width; 97 let y = frame.y; 98 for (let i = 0; i < res.length; i++) { 99 let it = res[i]; 100 if((it.startNS || 0) > startNS && (it.startNS || 0) < endNS){ 101 if (!it.frame) { 102 it.frame = {}; 103 it.frame.y = y; 104 } 105 it.frame.height = it.height; 106 EnergyAnomalyStruct.setAnomalyFrame(it, pns, startNS, endNS, frame); 107 }else{ 108 it.frame = null; 109 } 110 } 111 return; 112 } 113 114 res.length = 0; 115 if (arr) { 116 let y = frame.y; 117 let pns = (endNS - startNS) / frame.width; 118 for (let index = 0; index < arr.length; index++) { 119 let item = arr[index]; 120 if (!item.frame) { 121 item.frame = {}; 122 item.frame.y = y; 123 } 124 item.frame.height = item.height; 125 if ((item.startNS + 50000) > (startNS || 0) && (item.startNS || 0) < (endNS || 0)) { 126 EnergyAnomalyStruct.setAnomalyFrame(item, pns, startNS || 0, endNS || 0, frame) 127 if ((item.appKey === "APPNAME" && item.Value.indexOf(appName) >= 0)) { 128 res.push(item) 129 } 130 if (item.appKey != "APPNAME") { 131 res.push(item) 132 } 133 } 134 } 135 } 136} 137 138export class EnergyAnomalyStruct extends BaseStruct { 139 static hoverEnergyAnomalyStruct: EnergyAnomalyStruct | undefined; 140 static selectEnergyAnomalyStruct: EnergyAnomalyStruct | undefined; 141 static SYSTEM_EXCEPTION = new Set(["ANOMALY_SCREEN_OFF_ENERGY", "ANOMALY_ALARM_WAKEUP", 142 "ANOMALY_KERNEL_WAKELOCK", "ANOMALY_CPU_HIGH_FREQUENCY", "ANOMALY_WAKEUP"]); 143 type: number | undefined 144 startNS: number | undefined 145 height: number | undefined 146 eventName: string | undefined 147 148 static draw(ctx: CanvasRenderingContext2D, path: Path2D, data: EnergyAnomalyStruct) { 149 if (data.frame) { 150 EnergyAnomalyStruct.drawRoundRectPath(ctx, data.frame.x - 7, 20 - 7, 14, data) 151 } 152 153 } 154 155 static drawRoundRectPath(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, data: EnergyAnomalyStruct) { 156 ctx.beginPath(); 157 ctx.arc(x + 7, y + 22, 3, 0, Math.PI * 2); 158 ctx.closePath(); 159 let color = ""; 160 if(EnergyAnomalyStruct.SYSTEM_EXCEPTION.has(<string>data.eventName)){ 161 color = '#E64566'; 162 }else { 163 color = "#FFC880"; 164 } 165 // 填充背景颜色 166 ctx.fillStyle = color; 167 ctx.fill(); 168 // 填充边框颜色 169 ctx.lineWidth = width; 170 ctx.lineCap = 'round' 171 ctx.strokeStyle = color 172 ctx.stroke(); 173 // 填充文字颜色 174 ctx.font = "12px Arial"; 175 ctx.fillStyle = ColorUtils.GREY_COLOR; 176 ctx.textAlign = "center"; 177 ctx.fillText("E", x + 7, y + 23); 178 } 179 180 static setAnomalyFrame(node: any, pns: number, startNS: number, endNS: number, frame: any) { 181 if ((node.startNS || 0) < startNS) { 182 node.frame.x = 0; 183 } else { 184 node.frame.x = Math.floor(((node.startNS || 0) - startNS) / pns); 185 } 186 if ((node.startNS || 0) > endNS) { 187 node.frame.width = frame.width - node.frame.x; 188 } else { 189 node.frame.width = Math.ceil(((node.startNS || 0) - startNS) / pns - node.frame.x); 190 } 191 if (node.frame.width < 1) { 192 node.frame.width = 1; 193 } 194 } 195} 196 197 198 199 200 201