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.js"; 17import {query, queryAllHeapByEvent, queryHeapGroupByEvent, queryNativeHookProcess} from "../../database/SqlLite.js"; 18import {TraceRow} from "../trace/base/TraceRow.js"; 19import {info} from "../../../log/Log.js"; 20import {procedurePool} from "../../database/Procedure.js"; 21import {HeapStruct} from "../../bean/HeapStruct.js"; 22import {NativeEvent, NativeEventHeap} from "../../bean/NativeHook.js"; 23 24export class SpNativeMemoryChart { 25 static EVENT_HEAP: Array<NativeEventHeap> = []; 26 private trace: SpSystemTrace; 27 28 constructor(trace: SpSystemTrace) { 29 this.trace = trace; 30 } 31 32 initChart = async () => { 33 let time = new Date().getTime(); 34 let nativeProcess = await queryNativeHookProcess(); 35 info("NativeHook Process data size is: ", nativeProcess!.length) 36 if (nativeProcess.length == 0) { 37 return; 38 } 39 SpNativeMemoryChart.EVENT_HEAP = await queryHeapGroupByEvent(); 40 let nativeRow = new TraceRow({ 41 canvasNumber: 1, 42 alpha: false, 43 contextId: '2d', 44 isOffScreen: SpSystemTrace.isCanvasOffScreen 45 }); 46 let process = ""; 47 if (nativeProcess.length > 0) { 48 process = ` ${nativeProcess[0].pid}` 49 } 50 nativeRow.rowId = `native-memory` 51 nativeRow.index = 0; 52 nativeRow.rowType = TraceRow.ROW_TYPE_NATIVE_MEMORY 53 nativeRow.drawType = 0; 54 nativeRow.rowParentId = ''; 55 nativeRow.folder = true; 56 nativeRow.name = `Native Memory` + process; 57 nativeRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 58 nativeRow.selectChangeHandler = this.trace.selectChangeHandler; 59 nativeRow.onDrawTypeChangeHandler = (type) => { 60 this.trace.rowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[row-type='heap']`).forEach(it => { 61 it.drawType = type; 62 it.isComplete = false; 63 it.draw(); 64 }) 65 }; 66 nativeRow.supplier = () => new Promise<Array<any>>((resolve, reject) => resolve([])); 67 nativeRow.onThreadHandler = (useCache) => { 68 procedurePool.submitWithName(`process${nativeRow.index}`, `native-memory`, { 69 list: nativeRow.must ? nativeRow.dataList : undefined, 70 offscreen: !nativeRow.isTransferCanvas ? nativeRow.offscreen[0] : undefined, 71 xs: TraceRow.range?.xs, 72 dpr: nativeRow.dpr, 73 isHover: nativeRow.isHover, 74 flagMoveInfo: this.trace.hoverFlag, 75 flagSelectedInfo: this.trace.selectFlag, 76 hoverX: nativeRow.hoverX, 77 hoverY: nativeRow.hoverY, 78 canvasWidth: nativeRow.canvasWidth, 79 canvasHeight: nativeRow.canvasHeight, 80 isRangeSelect: nativeRow.rangeSelect, 81 rangeSelectObject: TraceRow.rangeSelectObject, 82 useCache: useCache, 83 lineColor: nativeRow.getLineColor(), 84 startNS: TraceRow.range?.startNS || 0, 85 endNS: TraceRow.range?.endNS || 0, 86 totalNS: TraceRow.range?.totalNS || 0, 87 slicesTime: TraceRow.range?.slicesTime, 88 range: TraceRow.range, 89 frame: nativeRow.frame 90 }, !nativeRow.isTransferCanvas ? nativeRow.offscreen[0] : undefined, (res: any) => { 91 nativeRow.must = false; 92 }); 93 nativeRow.isTransferCanvas = true; 94 } 95 96 this.trace.rowsEL?.appendChild(nativeRow) 97 /** 98 * 添加heap信息 99 */ 100 let native_memory = ["All Heap & Anonymous VM", "All Heap", "All Anonymous VM"]; 101 for (let i = 0; i < native_memory.length; i++) { 102 let nm = native_memory[i]; 103 let allHeapRow = new TraceRow<HeapStruct>({ 104 canvasNumber: 1, 105 alpha: false, 106 contextId: '2d', 107 isOffScreen: true 108 }); 109 allHeapRow.index = i; 110 allHeapRow.rowParentId = `native-memory` 111 allHeapRow.rowHidden = !nativeRow.expansion 112 allHeapRow.style.height = '40px' 113 allHeapRow.name = nm; 114 allHeapRow.rowId = nm; 115 allHeapRow.drawType = 0; 116 allHeapRow.folder = false; 117 allHeapRow.rowType = TraceRow.ROW_TYPE_HEAP; 118 allHeapRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 119 allHeapRow.selectChangeHandler = this.trace.selectChangeHandler; 120 allHeapRow.setAttribute('children', '') 121 allHeapRow.supplier = () => { 122 return this.getNativeMemoryDataByChartType(i, allHeapRow.drawType) 123 } 124 allHeapRow.onThreadHandler = (useCache) => { 125 procedurePool.submitWithName(`process${allHeapRow.index}`, `heap-${nm}`, { 126 list: allHeapRow.must ? allHeapRow.dataList : undefined, 127 offscreen: !allHeapRow.isTransferCanvas ? allHeapRow.offscreen[0] : undefined, 128 xs: TraceRow.range?.xs, 129 dpr: allHeapRow.dpr, 130 isHover: allHeapRow.isHover, 131 flagMoveInfo: this.trace.hoverFlag, 132 flagSelectedInfo: this.trace.selectFlag, 133 hoverX: allHeapRow.hoverX, 134 hoverY: allHeapRow.hoverY, 135 canvasWidth: allHeapRow.canvasWidth, 136 canvasHeight: allHeapRow.canvasHeight, 137 isRangeSelect: allHeapRow.rangeSelect, 138 rangeSelectObject: TraceRow.rangeSelectObject, 139 useCache: useCache, 140 lineColor: allHeapRow.getLineColor(), 141 startNS: TraceRow.range?.startNS || 0, 142 endNS: TraceRow.range?.endNS || 0, 143 totalNS: TraceRow.range?.totalNS || 0, 144 slicesTime: TraceRow.range?.slicesTime, 145 range: TraceRow.range, 146 frame: allHeapRow.frame 147 }, !allHeapRow.isTransferCanvas ? allHeapRow.offscreen[0] : undefined, (res: any, hover: any) => { 148 allHeapRow.must = false; 149 if (allHeapRow.isHover) { 150 HeapStruct.hoverHeapStruct = hover; 151 } 152 }); 153 allHeapRow.isTransferCanvas = true; 154 } 155 this.trace.rowsEL?.appendChild(allHeapRow) 156 } 157 let durTime = new Date().getTime() - time; 158 info('The time to load the Native Memory data is: ', durTime) 159 } 160 161 getNativeMemoryDataByChartType = async (nativeMemoryType: number, chartType: number): Promise<Array<HeapStruct>> => { 162 let args = new Map<string,any>(); 163 args.set("nativeMemoryType",nativeMemoryType); 164 args.set("chartType",chartType); 165 args.set("totalNS",TraceRow.range?.totalNS!); 166 args.set("actionType","memory-chart"); 167 let arr:Array<HeapStruct> = await new Promise<any>((resolve, reject) => { 168 procedurePool.submitWithName("logic1","native-memory-action",args,undefined,(res:any)=>{ 169 resolve(res) 170 }) 171 }) 172 return arr; 173 } 174 175 initNativeMemory = async () => { 176 let time = new Date().getTime(); 177 await new Promise<any>((resolve, reject) => { 178 procedurePool.submitWithName("logic1","native-memory-init",{},undefined,(res:any)=>{ 179 resolve(res) 180 }) 181 }) 182 let durTime = new Date().getTime() - time; 183 info('The time to init the native memory data is: ', durTime) 184 } 185 186}