1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace';
17fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow';
18fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker';
19fb726d48Sopenharmony_ciimport { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil';
20fb726d48Sopenharmony_ciimport { BaseStruct } from '../../bean/BaseStruct';
21fb726d48Sopenharmony_ciimport { folderSupplier, rowThreadHandler } from './SpChartManager';
22fb726d48Sopenharmony_ciimport { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU';
23fb726d48Sopenharmony_ciimport { TraceRowConfig } from '../trace/base/TraceRowConfig';
24fb726d48Sopenharmony_ciimport { ProcessMemStruct } from '../../bean/ProcessMemStruct';
25fb726d48Sopenharmony_ciimport { MemRender } from '../../database/ui-worker/ProcedureWorkerMem';
26fb726d48Sopenharmony_ciimport { FuncRender, FuncStruct } from '../../database/ui-worker/ProcedureWorkerFunc';
27fb726d48Sopenharmony_ciimport { ThreadRender } from '../../database/ui-worker/ProcedureWorkerThread';
28fb726d48Sopenharmony_ciimport { promises } from 'dns';
29fb726d48Sopenharmony_ciconst FOLD_HEIGHT = 24;
30fb726d48Sopenharmony_ciexport class SpImportUserPluginsChart {
31fb726d48Sopenharmony_ci	private trace: SpSystemTrace;
32fb726d48Sopenharmony_ci	static userPluginData: [];
33fb726d48Sopenharmony_ci	private traceId?: string | undefined;
34fb726d48Sopenharmony_ci
35fb726d48Sopenharmony_ci	constructor(trace: SpSystemTrace) {
36fb726d48Sopenharmony_ci		this.trace = trace;
37fb726d48Sopenharmony_ci	}
38fb726d48Sopenharmony_ci
39fb726d48Sopenharmony_ci	async init(traceId?: string): Promise<void> {
40fb726d48Sopenharmony_ci		this.traceId = traceId;
41fb726d48Sopenharmony_ci		//@ts-ignore
42fb726d48Sopenharmony_ci		let folderRow = this.createFolderRow(this.traceId);
43fb726d48Sopenharmony_ci		folderRow.rowId = 'UserPluginsRows';
44fb726d48Sopenharmony_ci		folderRow.rowType = TraceRow.ROW_TYPE_IMPORT;
45fb726d48Sopenharmony_ci		folderRow.name = 'UserPluginsRows';
46fb726d48Sopenharmony_ci		folderRow.selectChangeHandler = this.trace.selectChangeHandler;
47fb726d48Sopenharmony_ci		this.trace.rowsEL?.appendChild(folderRow);
48fb726d48Sopenharmony_ci	}
49fb726d48Sopenharmony_ci
50fb726d48Sopenharmony_ci	createFolderRow(traceId?: string): TraceRow<BaseStruct> {
51fb726d48Sopenharmony_ci		let folder = TraceRow.skeleton<BaseStruct>(traceId);
52fb726d48Sopenharmony_ci		folder.rowParentId = '';
53fb726d48Sopenharmony_ci		folder.folder = true;
54fb726d48Sopenharmony_ci		folder.style.height = '40px';
55fb726d48Sopenharmony_ci		folder.rowHidden = folder.expansion;
56fb726d48Sopenharmony_ci		folder.summaryProtoPid = [];
57fb726d48Sopenharmony_ci		folder.setAttribute('children', '');
58fb726d48Sopenharmony_ci		folder.supplier = folderSupplier();
59fb726d48Sopenharmony_ci		folder.onThreadHandler = folderThreadHandler(folder, this.trace);
60fb726d48Sopenharmony_ci		folder.addRowSampleUpload();
61fb726d48Sopenharmony_ci		this.addTraceRowEventListener(folder);
62fb726d48Sopenharmony_ci		return folder;
63fb726d48Sopenharmony_ci	}
64fb726d48Sopenharmony_ci
65fb726d48Sopenharmony_ci	/**
66fb726d48Sopenharmony_ci	 * 监听文件上传事件
67fb726d48Sopenharmony_ci	 * @param row 
68fb726d48Sopenharmony_ci	 * @param start_ts 
69fb726d48Sopenharmony_ci	 */
70fb726d48Sopenharmony_ci	addTraceRowEventListener(row: TraceRow<BaseStruct>): void {
71fb726d48Sopenharmony_ci		row.uploadEl?.addEventListener('sample-file-change', (e: unknown) => {
72fb726d48Sopenharmony_ci			this.getJsonData(e).then((res: unknown) => {
73fb726d48Sopenharmony_ci				if (row.childrenList.length) { this.handleDynamicRowList(row); }
74fb726d48Sopenharmony_ci				//@ts-ignore
75fb726d48Sopenharmony_ci				if (res && res.data) {
76fb726d48Sopenharmony_ci					let len = TraceRowConfig.allTraceRowList.length;
77fb726d48Sopenharmony_ci					//@ts-ignore
78fb726d48Sopenharmony_ci					res.data.forEach(item => {
79fb726d48Sopenharmony_ci						//支持mem,thread, func
80fb726d48Sopenharmony_ci						if (![TraceRow.ROW_TYPE_MEM, TraceRow.ROW_TYPE_THREAD, TraceRow.ROW_TYPE_FUNC].includes(item.rowType)) {
81fb726d48Sopenharmony_ci							return;
82fb726d48Sopenharmony_ci						}
83fb726d48Sopenharmony_ci						for (let index = 0; index < len - 1; index++) {
84fb726d48Sopenharmony_ci							const element = TraceRowConfig.allTraceRowList[index];
85fb726d48Sopenharmony_ci							if (element.rowType === item.rowType && element.name === item.threadName) {
86fb726d48Sopenharmony_ci								//@ts-ignore
87fb726d48Sopenharmony_ci								let parentRows = this.trace.shadowRoot?.querySelectorAll<TraceRow<unknown>>(`trace-row[row-id='${element.rowParentId}']`);
88fb726d48Sopenharmony_ci								let childRow = TraceRow.skeleton<BaseStruct>();
89fb726d48Sopenharmony_ci								//@ts-ignore
90fb726d48Sopenharmony_ci								childRow.rowId = element.rowId;
91fb726d48Sopenharmony_ci								childRow.rowType = element.rowType;
92fb726d48Sopenharmony_ci								childRow.protoParentId = parentRows?.[0].name;
93fb726d48Sopenharmony_ci								childRow.protoPid = element.rowParentId!;
94fb726d48Sopenharmony_ci								childRow.rowParentId = 'UserPluginsRows';
95fb726d48Sopenharmony_ci								childRow.rowHidden = element.rowHidden;
96fb726d48Sopenharmony_ci								childRow.style.width = childRow.style.width;
97fb726d48Sopenharmony_ci								childRow.style.height = element.style.height;
98fb726d48Sopenharmony_ci								childRow.enableCollapseChart(FOLD_HEIGHT, this.trace);
99fb726d48Sopenharmony_ci								//@ts-ignore
100fb726d48Sopenharmony_ci								childRow.name = element.name;
101fb726d48Sopenharmony_ci								childRow.setAttribute('children', '');
102fb726d48Sopenharmony_ci								childRow.needRefresh = true;
103fb726d48Sopenharmony_ci								childRow.favoriteChangeHandler = element.favoriteChangeHandler;
104fb726d48Sopenharmony_ci								childRow.selectChangeHandler = element.selectChangeHandler;
105fb726d48Sopenharmony_ci								this.addDrawAttributes(item, childRow, element);
106fb726d48Sopenharmony_ci								row.summaryProtoPid!.push(childRow.protoPid);
107fb726d48Sopenharmony_ci								row.addChildTraceRow(childRow);
108fb726d48Sopenharmony_ci							};
109fb726d48Sopenharmony_ci						};
110fb726d48Sopenharmony_ci					});
111fb726d48Sopenharmony_ci					row.expansion = true;
112fb726d48Sopenharmony_ci				};
113fb726d48Sopenharmony_ci				this.trace.refreshCanvas(false);
114fb726d48Sopenharmony_ci			});
115fb726d48Sopenharmony_ci		});
116fb726d48Sopenharmony_ci	}
117fb726d48Sopenharmony_ci	//清空row-parent-id='UserPluginsRows'动态添加的子Row的list数据
118fb726d48Sopenharmony_ci	handleDynamicRowList(row: TraceRow<BaseStruct>): void {
119fb726d48Sopenharmony_ci		row.summaryProtoPid = [];
120fb726d48Sopenharmony_ci		// 使用querySelectorAll找到所有row-parent-id='UserPluginsRows'的div元素
121fb726d48Sopenharmony_ci		//@ts-ignore
122fb726d48Sopenharmony_ci		let childRows: Array<TraceRow<unknown>> = [
123fb726d48Sopenharmony_ci			//@ts-ignore
124fb726d48Sopenharmony_ci			...this.trace.shadowRoot!.querySelectorAll<TraceRow<unknown>>(`trace-row[row-parent-id='UserPluginsRows']`),
125fb726d48Sopenharmony_ci		];
126fb726d48Sopenharmony_ci		// 遍历这些元素  
127fb726d48Sopenharmony_ci		childRows.forEach((div) => {
128fb726d48Sopenharmony_ci			// 如果等于,则从父节点中删除该元素  
129fb726d48Sopenharmony_ci			if (div.parentNode) {
130fb726d48Sopenharmony_ci				div.parentNode.removeChild(div);
131fb726d48Sopenharmony_ci			}
132fb726d48Sopenharmony_ci		});
133fb726d48Sopenharmony_ci		//删除上一次导入file添加的row
134fb726d48Sopenharmony_ci		TraceRowConfig.allTraceRowList = TraceRowConfig.allTraceRowList.filter(item => item.rowParentId !== 'UserPluginsRows');
135fb726d48Sopenharmony_ci		row.expansion = false;
136fb726d48Sopenharmony_ci		row.childrenList = [];
137fb726d48Sopenharmony_ci	}
138fb726d48Sopenharmony_ci
139fb726d48Sopenharmony_ci	addDrawAttributes(item: { rowType: string, threadName: string }, childRow: TraceRow<BaseStruct>, element: unknown): void {
140fb726d48Sopenharmony_ci		//@ts-ignore
141fb726d48Sopenharmony_ci		if (element.supplier) {
142fb726d48Sopenharmony_ci			//@ts-ignore
143fb726d48Sopenharmony_ci			childRow.supplier = async (): Promise<unknown> => {
144fb726d48Sopenharmony_ci				//@ts-ignore
145fb726d48Sopenharmony_ci				let res = await element.supplier!();
146fb726d48Sopenharmony_ci				return res;
147fb726d48Sopenharmony_ci			};
148fb726d48Sopenharmony_ci			//@ts-ignore
149fb726d48Sopenharmony_ci		} else if (element.supplierFrame) {
150fb726d48Sopenharmony_ci			//@ts-ignore
151fb726d48Sopenharmony_ci			childRow.supplierFrame = async (): Promise<unknown> => {
152fb726d48Sopenharmony_ci				//@ts-ignore
153fb726d48Sopenharmony_ci				let res = await element.supplierFrame!();
154fb726d48Sopenharmony_ci				return res;
155fb726d48Sopenharmony_ci			};
156fb726d48Sopenharmony_ci		}
157fb726d48Sopenharmony_ci		if (item.rowType === TraceRow.ROW_TYPE_MEM) {//处理mem
158fb726d48Sopenharmony_ci			childRow.findHoverStruct = (): void => {
159fb726d48Sopenharmony_ci				//@ts-ignore
160fb726d48Sopenharmony_ci				ProcessMemStruct.hoverProcessMemStruct = childRow.getHoverStruct(false);
161fb726d48Sopenharmony_ci			};
162fb726d48Sopenharmony_ci			childRow.focusHandler = (): void => {
163fb726d48Sopenharmony_ci				if (childRow.hoverY <= 5 || childRow.hoverY >= 35) {
164fb726d48Sopenharmony_ci					ProcessMemStruct.hoverProcessMemStruct = undefined;
165fb726d48Sopenharmony_ci				}
166fb726d48Sopenharmony_ci				this.trace.displayTip(
167fb726d48Sopenharmony_ci					childRow,
168fb726d48Sopenharmony_ci					ProcessMemStruct.hoverProcessMemStruct,
169fb726d48Sopenharmony_ci					`<span>${ProcessMemStruct.hoverProcessMemStruct?.value || '0'}</span>`
170fb726d48Sopenharmony_ci				);
171fb726d48Sopenharmony_ci			};
172fb726d48Sopenharmony_ci			childRow.onThreadHandler = rowThreadHandler<MemRender>('mem', 'context',
173fb726d48Sopenharmony_ci				//@ts-ignore
174fb726d48Sopenharmony_ci				{ type: `mem ${element.rowId} ${element.name}` }, childRow, this.trace);
175fb726d48Sopenharmony_ci		} else if (item.rowType === TraceRow.ROW_TYPE_FUNC) {
176fb726d48Sopenharmony_ci			//处理func
177fb726d48Sopenharmony_ci			//@ts-ignore
178fb726d48Sopenharmony_ci			if (element.asyncFuncName) {
179fb726d48Sopenharmony_ci				//@ts-ignore
180fb726d48Sopenharmony_ci				childRow.asyncFuncName = element.asyncFuncName;
181fb726d48Sopenharmony_ci				//@ts-ignore
182fb726d48Sopenharmony_ci				childRow.asyncFuncNamePID = element.asyncFuncNamePID;
183fb726d48Sopenharmony_ci				//@ts-ignore
184fb726d48Sopenharmony_ci				childRow.asyncFuncStartTID = element.asyncFuncStartTID;
185fb726d48Sopenharmony_ci			}
186fb726d48Sopenharmony_ci			//@ts-ignore
187fb726d48Sopenharmony_ci			if (element.asyncFuncThreadName) {
188fb726d48Sopenharmony_ci				//@ts-ignore
189fb726d48Sopenharmony_ci				childRow.asyncFuncThreadName = element.asyncFuncThreadName;
190fb726d48Sopenharmony_ci				//@ts-ignore
191fb726d48Sopenharmony_ci				childRow.asyncFuncNamePID = element.asyncFuncNamePID;
192fb726d48Sopenharmony_ci			}
193fb726d48Sopenharmony_ci			childRow.findHoverStruct = (): void => {
194fb726d48Sopenharmony_ci				//@ts-ignore
195fb726d48Sopenharmony_ci				FuncStruct.hoverFuncStruct = childRow.getHoverStruct();
196fb726d48Sopenharmony_ci			};
197fb726d48Sopenharmony_ci			childRow.onThreadHandler = rowThreadHandler<FuncRender>('func', 'context',
198fb726d48Sopenharmony_ci				//@ts-ignore
199fb726d48Sopenharmony_ci				{ type: '' }, childRow, this.trace);
200fb726d48Sopenharmony_ci		} else if (item.rowType === TraceRow.ROW_TYPE_THREAD) {
201fb726d48Sopenharmony_ci			//处理thread
202fb726d48Sopenharmony_ci			childRow.onThreadHandler = rowThreadHandler<ThreadRender>('thread', 'context',
203fb726d48Sopenharmony_ci				{ type: '', translateY: childRow.translateY }, childRow, this.trace);
204fb726d48Sopenharmony_ci		}
205fb726d48Sopenharmony_ci	}
206fb726d48Sopenharmony_ci	/**
207fb726d48Sopenharmony_ci	 * 获取上传的文件内容 转为json格式
208fb726d48Sopenharmony_ci	 * @param file 
209fb726d48Sopenharmony_ci	 * @returns 
210fb726d48Sopenharmony_ci	 */
211fb726d48Sopenharmony_ci	getJsonData(file: unknown): Promise<unknown> {
212fb726d48Sopenharmony_ci		return new Promise((resolve, reject) => {
213fb726d48Sopenharmony_ci			let reader = new FileReader();
214fb726d48Sopenharmony_ci			//@ts-ignore
215fb726d48Sopenharmony_ci			reader.readAsText(file.detail || file);
216fb726d48Sopenharmony_ci			reader.onloadend = (e: unknown): void => {
217fb726d48Sopenharmony_ci				//@ts-ignore
218fb726d48Sopenharmony_ci				const fileContent = e.target?.result;
219fb726d48Sopenharmony_ci				try {
220fb726d48Sopenharmony_ci					resolve(JSON.parse(fileContent));
221fb726d48Sopenharmony_ci					document.dispatchEvent(
222fb726d48Sopenharmony_ci						new CustomEvent('file-correct')
223fb726d48Sopenharmony_ci					);
224fb726d48Sopenharmony_ci					SpStatisticsHttpUtil.addOrdinaryVisitAction({
225fb726d48Sopenharmony_ci						event: 'seach-row',
226fb726d48Sopenharmony_ci						action: 'seach-row',
227fb726d48Sopenharmony_ci					});
228fb726d48Sopenharmony_ci				} catch (error) {
229fb726d48Sopenharmony_ci					document.dispatchEvent(
230fb726d48Sopenharmony_ci						new CustomEvent('file-error')
231fb726d48Sopenharmony_ci					);
232fb726d48Sopenharmony_ci				}
233fb726d48Sopenharmony_ci			};
234fb726d48Sopenharmony_ci		});
235fb726d48Sopenharmony_ci	}
236fb726d48Sopenharmony_ci}
237fb726d48Sopenharmony_ciexport const folderThreadHandler = (row: TraceRow<BaseStruct>, trace: SpSystemTrace) => {
238fb726d48Sopenharmony_ci	return (useCache: boolean): void => {
239fb726d48Sopenharmony_ci		row.canvasSave(trace.canvasPanelCtx!);
240fb726d48Sopenharmony_ci		if (row.expansion) {
241fb726d48Sopenharmony_ci			// @ts-ignore
242fb726d48Sopenharmony_ci			trace.canvasPanelCtx?.clearRect(0, 0, row.frame.width, row.frame.height);
243fb726d48Sopenharmony_ci		} else {
244fb726d48Sopenharmony_ci			(renders.empty as EmptyRender).renderMainThread(
245fb726d48Sopenharmony_ci				{
246fb726d48Sopenharmony_ci					context: trace.canvasPanelCtx,
247fb726d48Sopenharmony_ci					useCache: useCache,
248fb726d48Sopenharmony_ci					type: '',
249fb726d48Sopenharmony_ci				},
250fb726d48Sopenharmony_ci				row
251fb726d48Sopenharmony_ci			);
252fb726d48Sopenharmony_ci		}
253fb726d48Sopenharmony_ci		row.canvasRestore(trace.canvasPanelCtx!, trace);
254fb726d48Sopenharmony_ci	};
255fb726d48Sopenharmony_ci};
256fb726d48Sopenharmony_ci
257