• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {BaseElement, element} from "../../base-ui/BaseElement.js";
17import "../../base-ui/popover/LitPopover.js"
18import "../../base-ui/button/LitButton.js";
19import {LitMainMenuGroup} from "../../base-ui/menu/LitMainMenuGroup.js";
20import {LitMainMenuItem} from "../../base-ui/menu/LitMainMenuItem.js";
21import {SpRecordSetting} from "./setting/SpRecordSetting.js";
22import {LitMainMenu, MenuGroup, MenuItem} from "../../base-ui/menu/LitMainMenu.js";
23import {SpProbesConfig} from "./setting/SpProbesConfig.js";
24import {SpTraceCommand} from "./setting/SpTraceCommand.js";
25
26import {
27    CpuConfig,
28    CreateSessionRequest,
29    DiskioConfig, FileSystemConfig,
30    FpsConfig,
31    HilogConfig,
32    HiperfPluginConfig, HiSystemEventConfig,
33    levelFromJSON,
34    MemoryConfig,
35    NativeHookConfig,
36    NetworkConfig,
37    ProcessConfig,
38    ProfilerPluginConfig,
39    ProfilerSessionConfig,
40    ProfilerSessionConfigBufferConfig,
41    ProfilerSessionConfigBufferConfigPolicy,
42    ProfilerSessionConfigMode,
43    sysMeminfoTypeFromJSON,
44    sysVMeminfoTypeFromJSON,
45    TracePluginConfig,
46    Type
47} from "./setting/bean/ProfilerServiceTypes.js";
48import {PluginConvertUtils} from "./setting/utils/PluginConvertUtils.js";
49import {SpAllocations} from "./setting/SpAllocations.js";
50import {SpRecordPerf} from "./setting/SpRecordPerf.js";
51import {HdcDeviceManager} from "../../hdc/HdcDeviceManager.js";
52import {LitButton} from "../../base-ui/button/LitButton.js";
53import {SpApplication} from "../SpApplication.js";
54import {LitSearch} from "./trace/search/Search.js";
55import {LitProgressBar} from "../../base-ui/progress-bar/LitProgressBar.js";
56import {info, log} from "../../log/Log.js";
57import {CmdConstant} from "../../command/CmdConstant.js";
58import {Cmd} from "../../command/Cmd.js";
59import {SpFileSystem} from "./setting/SpFileSystem.js";
60import {SpSdkConfig} from "./setting/SpSdkConfig.js";
61import {SpVmTracker} from "./setting/SpVmTracker.js";
62
63@element('sp-record-trace')
64export class SpRecordTrace extends BaseElement {
65    public static serialNumber: string = '';
66    // 1GB
67    public static MaxFileSize: number = 1024 * 1024 * 1024;
68    public static isVscode = false;
69
70    set vs(vs: boolean) {
71        if (vs) {
72            SpRecordTrace.isVscode = true;
73            this.setAttribute("vs", '')
74        } else {
75            SpRecordTrace.isVscode = false;
76            this.removeAttribute("vs");
77        }
78    }
79
80    get vs(): boolean {
81        return this.hasAttribute("vs");
82    }
83
84    static MEM_INFO = ["MEMINFO_ACTIVE", "MEMINFO_ACTIVE_ANON", "MEMINFO_ACTIVE_FILE", "MEMINFO_ANON_PAGES", "MEMINFO_BUFFERS",
85        "MEMINFO_CACHED", "MEMINFO_CMA_FREE", "MEMINFO_CMA_TOTAL", "MEMINFO_COMMIT_LIMIT", "MEMINFO_COMMITED_AS",
86        "MEMINFO_DIRTY", "MEMINFO_INACTIVE", "MEMINFO_INACTIVE_ANON", "MEMINFO_INACTIVE_FILE",
87        "MEMINFO_KERNEL_STACK", "MEMINFO_MAPPED", "MEMINFO_MEM_AVAILABLE", "MEMINFO_MEM_FREE", "MEMINFO_MEM_TOTAL",
88        "MEMINFO_MLOCKED", "MEMINFO_PAGE_TABLES", "MEMINFO_SHMEM", "MEMINFO_SLAB", "MEMINFO_SLAB_RECLAIMABLE",
89        "MEMINFO_SLAB_UNRECLAIMABLE", "MEMINFO_SWAP_CACHED", "MEMINFO_SWAP_FREE", "MEMINFO_SWAP_TOTAL",
90        "MEMINFO_UNEVICTABLE", "MEMINFO_VMALLOC_CHUNK", "MEMINFO_VMALLOC_TOTAL", "MEMINFO_VMALLOC_USED",
91        "MEMINFO_WRITEBACK", "MEMINFO_KERNEL_RECLAIMABLE"]
92    static VMEM_INFO = ["VMEMINFO_UNSPECIFIED", "VMEMINFO_NR_FREE_PAGES", "VMEMINFO_NR_ALLOC_BATCH",
93        "VMEMINFO_NR_INACTIVE_ANON", "VMEMINFO_NR_ACTIVE_ANON", "VMEMINFO_NR_INACTIVE_FILE",
94        "VMEMINFO_NR_ACTIVE_FILE", "VMEMINFO_NR_UNEVICTABLE", "VMEMINFO_NR_MLOCK", "VMEMINFO_NR_ANON_PAGES",
95        "VMEMINFO_NR_MAPPED", "VMEMINFO_NR_FILE_PAGES", "VMEMINFO_NR_DIRTY", "VMEMINFO_NR_WRITEBACK",
96        "VMEMINFO_NR_SLAB_RECLAIMABLE", "VMEMINFO_NR_SLAB_UNRECLAIMABLE", "VMEMINFO_NR_PAGE_TABLE_PAGES",
97        "VMEMINFO_NR_KERNEL_STACK", "VMEMINFO_NR_OVERHEAD", "VMEMINFO_NR_UNSTABLE", "VMEMINFO_NR_BOUNCE",
98        "VMEMINFO_NR_VMSCAN_WRITE", "VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM", "VMEMINFO_NR_WRITEBACK_TEMP",
99        "VMEMINFO_NR_ISOLATED_ANON", "VMEMINFO_NR_ISOLATED_FILE", "VMEMINFO_NR_SHMEM", "VMEMINFO_NR_DIRTIED",
100        "VMEMINFO_NR_WRITTEN", "VMEMINFO_NR_PAGES_SCANNED", "VMEMINFO_WORKINGSET_REFAULT",
101        "VMEMINFO_WORKINGSET_ACTIVATE", "VMEMINFO_WORKINGSET_NODERECLAIM", "VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES",
102        "VMEMINFO_NR_FREE_CMA", "VMEMINFO_NR_SWAPCACHE", "VMEMINFO_NR_DIRTY_THRESHOLD",
103        "VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD", "VMEMINFO_PGPGIN", "VMEMINFO_PGPGOUT", "VMEMINFO_PGPGOUTCLEAN",
104        "VMEMINFO_PSWPIN", "VMEMINFO_PSWPOUT", "VMEMINFO_PGALLOC_DMA"]
105    static VMEM_INFO_SECOND = ["VMEMINFO_PGALLOC_NORMAL", "VMEMINFO_PGALLOC_MOVABLE", "VMEMINFO_PGFREE", "VMEMINFO_PGACTIVATE",
106        "VMEMINFO_PGDEACTIVATE", "VMEMINFO_PGFAULT", "VMEMINFO_PGMAJFAULT", "VMEMINFO_PGREFILL_DMA",
107        "VMEMINFO_PGREFILL_NORMAL", "VMEMINFO_PGREFILL_MOVABLE", "VMEMINFO_PGSTEAL_KSWAPD_DMA",
108        "VMEMINFO_PGSTEAL_KSWAPD_NORMAL", "VMEMINFO_PGSTEAL_KSWAPD_MOVABLE", "VMEMINFO_PGSTEAL_DIRECT_DMA",
109        "VMEMINFO_PGSTEAL_DIRECT_NORMAL", "VMEMINFO_PGSTEAL_DIRECT_MOVABLE", "VMEMINFO_PGSCAN_KSWAPD_DMA",
110        "VMEMINFO_PGSCAN_KSWAPD_NORMAL", "VMEMINFO_PGSCAN_KSWAPD_MOVABLE", "VMEMINFO_PGSCAN_DIRECT_DMA",
111        "VMEMINFO_PGSCAN_DIRECT_NORMAL", "VMEMINFO_PGSCAN_DIRECT_MOVABLE", "VMEMINFO_PGSCAN_DIRECT_THROTTLE",
112        "VMEMINFO_PGINODESTEAL", "VMEMINFO_SLABS_SCANNED", "VMEMINFO_KSWAPD_INODESTEAL",
113        "VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY", "VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY", "VMEMINFO_PAGEOUTRUN",
114        "VMEMINFO_ALLOCSTALL", "VMEMINFO_PGROTATED", "VMEMINFO_DROP_PAGECACHE", "VMEMINFO_DROP_SLAB",
115        "VMEMINFO_PGMIGRATE_SUCCESS", "VMEMINFO_PGMIGRATE_FAIL", "VMEMINFO_COMPACT_MIGRATE_SCANNED",
116        "VMEMINFO_COMPACT_FREE_SCANNED", "VMEMINFO_COMPACT_ISOLATED", "VMEMINFO_COMPACT_STALL",
117        "VMEMINFO_COMPACT_FAIL", "VMEMINFO_COMPACT_SUCCESS", "VMEMINFO_COMPACT_DAEMON_WAKE",
118        "VMEMINFO_UNEVICTABLE_PGS_CULLED", "VMEMINFO_UNEVICTABLE_PGS_SCANNED", "VMEMINFO_UNEVICTABLE_PGS_RESCUED",
119        "VMEMINFO_UNEVICTABLE_PGS_MLOCKED", "VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED"]
120    static VMEM_INFO_THIRD = [
121        "VMEMINFO_UNEVICTABLE_PGS_CLEARED", "VMEMINFO_UNEVICTABLE_PGS_STRANDED", "VMEMINFO_NR_ZSPAGES",
122        "VMEMINFO_NR_ION_HEAP", "VMEMINFO_NR_GPU_HEAP", "VMEMINFO_ALLOCSTALL_DMA", "VMEMINFO_ALLOCSTALL_MOVABLE",
123        "VMEMINFO_ALLOCSTALL_NORMAL", "VMEMINFO_COMPACT_DAEMON_FREE_SCANNED",
124        "VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED", "VMEMINFO_NR_FASTRPC", "VMEMINFO_NR_INDIRECTLY_RECLAIMABLE",
125        "VMEMINFO_NR_ION_HEAP_POOL", "VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE", "VMEMINFO_NR_SHADOW_CALL_STACK_BYTES",
126        "VMEMINFO_NR_SHMEM_HUGEPAGES", "VMEMINFO_NR_SHMEM_PMDMAPPED", "VMEMINFO_NR_UNRECLAIMABLE_PAGES",
127        "VMEMINFO_NR_ZONE_ACTIVE_ANON", "VMEMINFO_NR_ZONE_ACTIVE_FILE", "VMEMINFO_NR_ZONE_INACTIVE_ANON",
128        "VMEMINFO_NR_ZONE_INACTIVE_FILE", "VMEMINFO_NR_ZONE_UNEVICTABLE", "VMEMINFO_NR_ZONE_WRITE_PENDING",
129        "VMEMINFO_OOM_KILL", "VMEMINFO_PGLAZYFREE", "VMEMINFO_PGLAZYFREED", "VMEMINFO_PGREFILL",
130        "VMEMINFO_PGSCAN_DIRECT", "VMEMINFO_PGSCAN_KSWAPD", "VMEMINFO_PGSKIP_DMA", "VMEMINFO_PGSKIP_MOVABLE",
131        "VMEMINFO_PGSKIP_NORMAL", "VMEMINFO_PGSTEAL_DIRECT", "VMEMINFO_PGSTEAL_KSWAPD", "VMEMINFO_SWAP_RA",
132        "VMEMINFO_SWAP_RA_HIT", "VMEMINFO_WORKINGSET_RESTORE"
133    ]
134    // sys.mem.total   sys.mem.free sys.mem.buffers sys.mem.cached  sys.mem.shmem  sys.mem.slab  sys.mem.swap.total
135    // sys.mem.swap.free sys.mem.mapped  sys.mem.vmalloc.used  sys.mem.page.tables  sys.mem.kernel.stack
136    // sys.mem.active sys.mem.inactive  sys.mem.unevictable  sys.mem.vmalloc.total sys.mem.slab.unreclaimable
137    // sys.mem.cma.total sys.mem.cma.free
138    static ABALITY_MEM_INFO = ["MEMINFO_MEM_TOTAL", "MEMINFO_MEM_FREE", "MEMINFO_BUFFERS", "MEMINFO_CACHED",
139        "MEMINFO_SHMEM", "MEMINFO_SLAB", "MEMINFO_SWAP_TOTAL", "MEMINFO_SWAP_FREE", "MEMINFO_MAPPED",
140        "MEMINFO_VMALLOC_USED", "MEMINFO_PAGE_TABLES", "MEMINFO_KERNEL_STACK", "MEMINFO_ACTIVE", "MEMINFO_INACTIVE",
141        "MEMINFO_UNEVICTABLE", "MEMINFO_VMALLOC_TOTAL", "MEMINFO_SLAB_UNRECLAIMABLE", "MEMINFO_CMA_TOTAL",
142        "MEMINFO_CMA_FREE", "MEMINFO_KERNEL_RECLAIMABLE"]
143
144    schedulingEvents = [
145        "sched/sched_switch",
146        "power/suspend_resume",
147        "sched/sched_wakeup",
148        "sched/sched_wakeup_new",
149        "sched/sched_waking",
150        "sched/sched_process_exit",
151        "sched/sched_process_free",
152        "task/task_newtask",
153        "task/task_rename"
154    ]
155    powerEvents = [
156        "regulator/regulator_set_voltage",
157        "regulator/regulator_set_voltage_complete",
158        "power/clock_enable",
159        "power/clock_disable",
160        "power/clock_set_rate",
161        "power/suspend_resume"
162    ]
163    cpuFreqEvents = [
164        "power/cpu_frequency",
165        "power/cpu_idle",
166        "power/suspend_resume"
167    ]
168    sysCallsEvents = [
169        "raw_syscalls/sys_enter",
170        "raw_syscalls/sys_exit"
171    ]
172    highFrequencyEvents = [
173        "mm_event/mm_event_record",
174        "kmem/rss_stat",
175        "ion/ion_stat",
176        "dmabuf_heap/dma_heap_stat",
177        "kmem/ion_heap_grow",
178        "kmem/ion_heap_shrink"
179    ]
180    advancedConfigEvents = ["sched/sched_switch",
181        "sched/sched_wakeup",
182        "sched/sched_wakeup_new",
183        "sched/sched_waking",
184        "sched/sched_process_exit",
185        "sched/sched_process_free",
186        "irq/irq_handler_entry",
187        "irq/irq_handler_exit",
188        "irq/softirq_entry",
189        "irq/softirq_exit",
190        "irq/softirq_raise",
191        "power/clock_disable",
192        "power/clock_enable",
193        "power/clock_set_rate",
194        "power/cpu_frequency",
195        "power/cpu_idle",
196        "clk/clk_disable",
197        "clk/clk_disable_complete",
198        "clk/clk_enable",
199        "clk/clk_enable_complete",
200        "clk/clk_set_rate",
201        "clk/clk_set_rate_complete",
202        "binder/binder_transaction",
203        "binder/binder_transaction_alloc_buf",
204        "binder/binder_transaction_received",
205        "binder/binder_lock",
206        "binder/binder_locked",
207        "binder/binder_unlock",
208        "workqueue/workqueue_execute_start",
209        "workqueue/workqueue_execute_end",
210        "oom/oom_score_adj_update",
211        "ftrace/print"
212    ]
213    private _menuItems: Array<MenuItem> | undefined
214
215    public deviceSelect: HTMLSelectElement | undefined;
216
217    private stopButtonEl: HTMLButtonElement | null | undefined;
218
219    private recordButton: LitButton | undefined;
220    private sp: SpApplication | undefined;
221    private progressEL: LitProgressBar | undefined;
222    private litSearch: LitSearch | undefined;
223    private addButton: LitButton | undefined | null;
224
225    private recordSetting: SpRecordSetting | undefined;
226    private probesConfig: SpProbesConfig | undefined;
227    private traceCommand: SpTraceCommand | undefined;
228    private spAllocations: SpAllocations | undefined;
229    private spRecordPerf: SpRecordPerf | undefined;
230    private spFileSystem: SpFileSystem | undefined;
231    private spSdkConfig: SpSdkConfig | undefined;
232    private spVmTracker: SpVmTracker | undefined;
233
234    private menuGroup: LitMainMenuGroup | undefined | null;
235    private appContent: HTMLElement | undefined | null;
236
237    compareArray(devs: Array<string>): boolean {
238        let clearFlag: boolean = false;
239        let optionArray = new Array();
240        if (devs.length != this.deviceSelect!.options.length) {
241            clearFlag = true
242        } else {
243            let optionArray = new Array();
244            for (let i = 0; i < this.deviceSelect!.options.length; i++) {
245                optionArray.push(this.deviceSelect!.options[i].value)
246            }
247            devs.forEach(value => {
248                if (optionArray.indexOf(value) == -1) {
249                    clearFlag = true
250                }
251            })
252        }
253        return clearFlag;
254    }
255
256    refreshDeviceList() {
257        if (this.vs) {
258            Cmd.execHdcCmd(CmdConstant.CMD_HDC_DEVICES, (res: string) => {
259                let devs: string[] = res.trim().replace(/\r\n/g, "\r").replace(/\n/g, "\r").split(/\r/);
260                if (devs.length == 1 && devs[0].indexOf("Empty") != -1) {
261                    this.deviceSelect!.innerHTML = '';
262                    return;
263                }
264                let clearFlag = this.compareArray(devs);
265                if (clearFlag) {
266                    this.deviceSelect!.innerHTML = '';
267                    for (let i = 0; i < devs.length; i++) {
268                        let dev = devs[i];
269                        let option = document.createElement("option")
270                        option.className = 'select'
271                        option.textContent = dev;
272                        this.deviceSelect!.appendChild(option)
273                        if (i == 0) {
274                            SpRecordTrace.serialNumber = option.value;
275                        }
276                    }
277                }
278            });
279        } else {
280            this.deviceSelect!.innerHTML = '';
281            HdcDeviceManager.getDevices().then((devs: USBDevice[]) => {
282                for (let len = 0; len < devs.length; len++) {
283                    let dev = devs[len];
284                    let option = document.createElement("option")
285                    option.className = 'select'
286                    if (typeof dev.serialNumber === "string") {
287                        option.value = dev.serialNumber;
288                    }
289                    option.textContent = dev!.serialNumber ? dev!.serialNumber!.toString() : 'hdc Device';
290                    this.deviceSelect!.appendChild(option)
291                    if (len == 0) {
292                        SpRecordTrace.serialNumber = option.value;
293                        HdcDeviceManager.connect(option.value).then(() => {
294                        });
295                    }
296                }
297            });
298        }
299    }
300
301    freshMenuDisable(disable: boolean) {
302        let mainMenu = this.sp!.shadowRoot?.querySelector('#main-menu') as LitMainMenu
303        mainMenu.menus?.forEach(men => {
304                men.children.forEach(child => {
305                        // @ts-ignore
306                        child.disabled = disable
307                    }
308                )
309            }
310        )
311        mainMenu.menus = mainMenu.menus;
312    }
313
314    set showHint(bool: boolean) {
315        if (bool) {
316            this.setAttribute("show_hint", '');
317        } else {
318            this.removeAttribute("show_hint");
319        }
320    }
321
322    private refreshDeviceTimer: any;
323
324    initElements(): void {
325        let parentElement = this.parentNode as HTMLElement;
326        parentElement.style.overflow = 'hidden'
327        this.addButton = this.shadowRoot?.querySelector<LitButton>(".add");
328        this.addButton!.addEventListener("click", () => {
329            if (this.vs) {
330                this.refreshDeviceList();
331            } else {
332                HdcDeviceManager.findDevice().then(usbDevices => {
333                    log(usbDevices)
334                    this.refreshDeviceList();
335                });
336            }
337        })
338        this.deviceSelect = this.shadowRoot?.querySelector("#device-select") as HTMLSelectElement;
339        this.deviceSelect!.onchange = () => {
340            let value = this.deviceSelect!.options[this.deviceSelect!.selectedIndex].value;
341            SpRecordTrace.serialNumber = value;
342            if (!this.vs) {
343                HdcDeviceManager.connect(value).then(() => {
344                });
345            }
346        }
347        if (navigator.usb) {
348            navigator.usb.addEventListener('connect', (ev: USBConnectionEvent) => {
349                this.usbConnectionListener(ev);
350            });
351            navigator.usb.addEventListener('disconnect', (ev: USBConnectionEvent) => {
352                this.usbDisConnectionListener(ev)
353            });
354        }
355        this.recordSetting = new SpRecordSetting();
356        this.probesConfig = new SpProbesConfig();
357        this.traceCommand = new SpTraceCommand();
358        this.spAllocations = new SpAllocations();
359        this.spRecordPerf = new SpRecordPerf();
360        this.spFileSystem = new SpFileSystem();
361        this.spSdkConfig = new SpSdkConfig();
362        this.spVmTracker = new SpVmTracker();
363        this.recordButton = this.shadowRoot?.querySelector(".record") as LitButton;
364        this.sp = document.querySelector("sp-application") as SpApplication;
365        this.progressEL = this.sp.shadowRoot?.querySelector('.progress') as LitProgressBar
366        this.litSearch = this.sp.shadowRoot?.querySelector('#lit-search') as LitSearch;
367        this.recordButton!.addEventListener("click", () => {
368            this.recordButtonListener()
369        })
370        this.spRecordPerf!.addEventListener("addProbe", (event: any) => {
371            this.showHint = false;
372        })
373        this.spAllocations!.addEventListener("addProbe", (event: any) => {
374            this.showHint = false;
375        })
376        this.probesConfig!.addEventListener("addProbe", (event: any) => {
377            this.showHint = false;
378        })
379
380        this.stopButtonEl = this.traceCommand!.shadowRoot?.querySelector<HTMLButtonElement>('#stop-button');
381        this.stopButtonEl!.addEventListener('click', ev => {
382            this.stopRecordListener();
383        })
384        this.menuGroup = this.shadowRoot?.querySelector('#menu-group') as LitMainMenuGroup
385        this.appContent = this.shadowRoot?.querySelector('#app-content') as HTMLElement
386        this.appContent.append(this.recordSetting)
387        this.initMenuItems();
388    }
389
390    stopRecordListener() {
391        if (this.vs) {
392            let cmd = Cmd.formatString(CmdConstant.CMS_HDC_STOP, [SpRecordTrace.serialNumber]);
393            Cmd.execHdcCmd(cmd, (res: string) => {
394                this.freshMenuDisable(false)
395                this.freshConfigMenuDisable(false)
396                this.progressEL!.loading = false
397                this.sp!.search = false;
398                this.litSearch!.clear();
399                this.recordButton!.style.pointerEvents = 'auto';
400                this.addButton!.style.pointerEvents = 'auto';
401                this.deviceSelect!.style.pointerEvents = 'auto';
402                this.traceCommand!.show = false;
403            })
404        } else {
405            let selectedOption = this.deviceSelect!.options[this.deviceSelect!.selectedIndex] as HTMLOptionElement;
406            HdcDeviceManager.connect(selectedOption.value).then(result => {
407                if (result) {
408                    this.freshMenuDisable(false)
409                    this.freshConfigMenuDisable(false)
410                    try {
411                        this.progressEL!.loading = false
412                        this.sp!.search = false;
413                        this.litSearch!.clear();
414                        this.recordButton!.style.pointerEvents = 'auto';
415                        this.addButton!.style.pointerEvents = 'auto';
416                        this.deviceSelect!.style.pointerEvents = 'auto';
417                        HdcDeviceManager.stopHiprofiler(CmdConstant.CMS_STOP, true).then(result => {
418                        })
419                    } catch (exception) {
420                        log(exception)
421                    }
422                    this.traceCommand!.show = false;
423                }
424            })
425        }
426    }
427
428    private initMenuItems() {
429        let that = this
430        this._menuItems = [
431            {
432                title: "Record setting",
433                icon: "properties",
434                fileChoose: false,
435                clickHandler: function (ev: InputEvent) {
436                    that.appContent!.innerHTML = ""
437                    that.appContent!.append(that.recordSetting!)
438                    that.freshMenuItemsStatus('Record setting')
439                }
440            },
441            {
442                title: "Trace command",
443                icon: "dbsetbreakpoint",
444                fileChoose: false,
445                clickHandler: function (ev: InputEvent) {
446                    that.freshMenuItemsStatus('Trace command')
447                    let request = that.makeRequest();
448                    that.appContent!.innerHTML = ""
449                    that.appContent!.append(that.traceCommand!)
450                    that.traceCommand!.hdcCommon =
451                        PluginConvertUtils.createHdcCmd(
452                            PluginConvertUtils.BeanToCmdTxt(request, false), that.recordSetting!.output, that.recordSetting!.maxDur)
453                }
454            },
455            {
456                title: "Probes config", icon: "realIntentionBulb", fileChoose: false,
457                clickHandler: function (ev: InputEvent) {
458                    that.appContent!.innerHTML = ""
459                    that.appContent!.append(that.probesConfig!)
460                    that.freshMenuItemsStatus('Probes config')
461                }
462            },
463            {
464                title: "Native Memory",
465                icon: "externaltools",
466                fileChoose: false,
467                clickHandler: function (ev: InputEvent) {
468                    that.appContent!.innerHTML = ""
469                    that.appContent!.append(that.spAllocations!)
470                    that.freshMenuItemsStatus('Native Memory')
471                }
472            },
473            {
474                title: "Hiperf", icon: "realIntentionBulb", fileChoose: false,
475                clickHandler: function (ev: InputEvent) {
476                    that.appContent!.innerHTML = ""
477                    that.appContent!.append(that.spRecordPerf!)
478                    that.freshMenuItemsStatus('Hiperf')
479                }
480            },
481            {
482                title: "eBPF Config", icon: "file-config", fileChoose: false,
483                clickHandler: function (ev: InputEvent) {
484                    that.appContent!.innerHTML = ""
485                    that.appContent!.append(that.spFileSystem!)
486                    that.freshMenuItemsStatus('eBPF Config')
487                }
488            },
489            {
490                title: "VM Tracker", icon: "vm-tracker", fileChoose: false,
491                clickHandler: function (ev: InputEvent) {
492                    that.appContent!.innerHTML = ""
493                    that.appContent!.append(that.spVmTracker!)
494                    that.freshMenuItemsStatus('VM Tracker')
495                }
496            },
497            {
498                title: "SDK Config", icon: "file-config", fileChoose: false,
499                clickHandler: function (ev: InputEvent) {
500                    that.appContent!.innerHTML = ""
501                    that.appContent!.append(that.spSdkConfig!)
502                    that.freshMenuItemsStatus('SDK Config')
503                }
504            }
505        ]
506        this._menuItems?.forEach(item => {
507            let th = new LitMainMenuItem();
508            th.setAttribute('icon', item.icon || "");
509            th.setAttribute('title', item.title || "");
510            th.style.height = "60px"
511            th.style.fontFamily = "Helvetica-Bold"
512            th.style.fontSize = "16px"
513            th.style.lineHeight = "28px"
514            th.style.fontWeight = "700"
515            th.style.opacity = "0.9"
516            th.removeAttribute('file');
517            th.addEventListener('click', e => {
518                if (item.clickHandler) {
519                    item.clickHandler(item)
520                }
521            })
522            this.menuGroup!.appendChild(th);
523        })
524    }
525
526    usbConnectionListener(event: USBConnectionEvent) {
527        if (event.isTrusted) {
528            let usbDevice: USBDevice = event.device;
529            let option = document.createElement("option")
530            option.className = 'select'
531            if (typeof usbDevice.serialNumber === "string") {
532                option.value = usbDevice.serialNumber;
533            }
534            option.selected = true;
535            option.textContent = usbDevice!.serialNumber ? usbDevice!.serialNumber.replace(/"/g, "")
536                : 'hdc Device';
537            this.deviceSelect!.appendChild(option)
538            SpRecordTrace.serialNumber = option.value;
539            HdcDeviceManager.connect(option.value).then(() => {
540            });
541        }
542    }
543
544    usbDisConnectionListener(event: USBConnectionEvent) {
545        let disConnectDevice: USBDevice = event.device;
546        for (let index = 0; index < this.deviceSelect!.children.length; index++) {
547            let option = this.deviceSelect!.children[index] as HTMLOptionElement;
548            if (option.value == disConnectDevice.serialNumber) {
549                let optValue = option.value;
550                HdcDeviceManager.disConnect(optValue).then(() => {
551                });
552                this.deviceSelect!.removeChild(option);
553                if (SpRecordTrace.serialNumber == optValue) {
554                    let options = this.deviceSelect!.options
555                    if (options.length > 0) {
556                        let selectedOpt = options[this.deviceSelect!.selectedIndex]
557                        SpRecordTrace.serialNumber = selectedOpt.value;
558                    } else {
559                        SpRecordTrace.serialNumber = '';
560                    }
561                }
562            }
563        }
564    }
565
566    recordButtonListener() {
567        let request = this.makeRequest();
568        if (request.pluginConfigs.length == 0) {
569            this.showHint = true;
570            return;
571        } else {
572            this.showHint = false;
573        }
574        let traceCommandStr = PluginConvertUtils.createHdcCmd(
575            PluginConvertUtils.BeanToCmdTxt(request, false), this.recordSetting!.output, this.recordSetting!.maxDur)
576        let selectedOption = this.deviceSelect!.options[this.deviceSelect!.selectedIndex] as HTMLOptionElement;
577        if (selectedOption) {
578            SpRecordTrace.serialNumber = selectedOption.value;
579        } else {
580            this.sp!.search = true;
581            this.litSearch!.clear();
582            this.progressEL!.loading = false
583            this.litSearch!.setPercent("please connect device", -1);
584        }
585        if (this.vs) {
586            this.appContent!.innerHTML = ""
587            this.appContent!.append(this.traceCommand!)
588            let config = this.makeRequest();
589            this.traceCommand!.hdcCommon =
590                PluginConvertUtils.createHdcCmd(
591                    PluginConvertUtils.BeanToCmdTxt(config, false), this.recordSetting!.output, this.recordSetting!.maxDur)
592            this.freshMenuItemsStatus('Trace command')
593            Cmd.execHdcCmd(Cmd.formatString(CmdConstant.CMS_HDC_STOP, [SpRecordTrace.serialNumber]), (stopRes: string) => {
594                let cmd = Cmd.formatString(CmdConstant.CMD_MOUNT_DEVICES, [SpRecordTrace.serialNumber]);
595                Cmd.execHdcCmd(cmd, (res: string) => {
596                    this.sp!.search = true;
597                    this.progressEL!.loading = true
598                    this.litSearch!.clear();
599                    this.litSearch!.setPercent("tracing  " + this.recordSetting!.maxDur * 1000 + "ms", -1);
600                    this.buttonDisable(true);
601                    this.traceCommand!.show = true;
602                    this.freshMenuDisable(true)
603                    this.freshConfigMenuDisable(true)
604                    Cmd.execHdcTraceCmd(traceCommandStr, SpRecordTrace.serialNumber, (traceResult: string) => {
605                        if (traceResult.indexOf("DestroySession done") != -1) {
606                            this.litSearch!.setPercent("tracing htrace down", -1);
607                            let cmd = Cmd.formatString(CmdConstant.CMD_FIEL_RECV_DEVICES, [SpRecordTrace.serialNumber, this.recordSetting!.output])
608                            Cmd.execFileRecv(cmd, this.recordSetting!.output, (rt: ArrayBuffer) => {
609                                this.litSearch!.setPercent("downloading Hitrace file ", 101);
610                                let fileName = this.recordSetting!.output.substring(this.recordSetting!.output.lastIndexOf("/") + 1)
611                                let file = new File([rt], fileName);
612                                let main = this!.parentNode!.parentNode!.querySelector("lit-main-menu") as LitMainMenu
613                                let children = main.menus as Array<MenuGroup>;
614                                let child = children[0].children as Array<MenuItem>
615                                let fileHandler = child[0].fileHandler;
616                                if (fileHandler) {
617                                    this.freshMenuDisable(false)
618                                    this.freshConfigMenuDisable(false)
619                                    fileHandler({detail: file})
620                                }
621                            })
622                        } else {
623                            this.litSearch!.setPercent("tracing htrace failed, please check your config ", -1);
624                        }
625                        this.buttonDisable(false);
626                    })
627                })
628            })
629        } else {
630            HdcDeviceManager.connect(selectedOption.value).then(result => {
631                    log("result is " + result);
632                    if (result) {
633                        this.appContent!.innerHTML = ""
634                        this.appContent!.append(this.traceCommand!)
635                        let config = this.makeRequest();
636                        this.traceCommand!.hdcCommon =
637                            PluginConvertUtils.createHdcCmd(
638                                PluginConvertUtils.BeanToCmdTxt(config, false), this.recordSetting!.output, this.recordSetting!.maxDur)
639                        this.freshMenuItemsStatus('Trace command')
640                        try {
641                            HdcDeviceManager.stopHiprofiler(CmdConstant.CMS_STOP, true).then(() => {
642                                HdcDeviceManager.shellResultAsString(CmdConstant.CMD_MOUNT, true).then(() => {
643                                    this.sp!.search = true;
644                                    this.progressEL!.loading = true
645                                    this.litSearch!.clear();
646                                    this.litSearch!.setPercent("tracing  " + this.recordSetting!.maxDur * 1000 + "ms", -1);
647                                    this.buttonDisable(true);
648                                    this.traceCommand!.show = true;
649                                    this.freshMenuDisable(true)
650                                    this.freshConfigMenuDisable(true)
651                                    HdcDeviceManager.shellResultAsString(CmdConstant.CMD_SHELL + traceCommandStr, false).then(traceResult => {
652                                        let re = this.isSuccess(traceResult)
653                                        if (re == 0) {
654                                            this.litSearch!.setPercent("tracing htrace down", -1);
655                                            HdcDeviceManager.shellResultAsString(CmdConstant.CMD_TRACE_FILE_SIZE + this.recordSetting!.output, false).then(traceFileSize => {
656                                                if (Number(traceFileSize) <= SpRecordTrace.MaxFileSize) {
657                                                    HdcDeviceManager.fileRecv(this.recordSetting!.output, (perNumber: number) => {
658                                                        this.litSearch!.setPercent("downloading Hitrace file ", perNumber);
659                                                    }).then(pullRes => {
660                                                        this.litSearch!.setPercent("downloading Hitrace file ", 101);
661                                                        pullRes.arrayBuffer().then(buffer => {
662                                                            let fileName = this.recordSetting!.output.substring(this.recordSetting!.output.lastIndexOf("/") + 1)
663                                                            let file = new File([buffer], fileName);
664                                                            let main = this!.parentNode!.parentNode!.querySelector("lit-main-menu") as LitMainMenu
665                                                            let children = main.menus as Array<MenuGroup>;
666                                                            let child = children[0].children as Array<MenuItem>
667                                                            let fileHandler = child[0].fileHandler;
668                                                            if (fileHandler) {
669                                                                this.freshConfigMenuDisable(false);
670                                                                this.freshMenuDisable(false)
671                                                                fileHandler({detail: file})
672                                                            }
673                                                        })
674                                                    });
675                                                } else {
676                                                    this.litSearch!.setPercent("htrace  file is too big", -1);
677                                                }
678                                            })
679                                        } else if (re == 2) {
680                                            this.litSearch!.setPercent("stop tracing htrace ", -1);
681                                        } else if (re == -1) {
682                                            this.litSearch!.setPercent("The device is abnormal", -1);
683                                            this.progressEL!.loading = false
684                                        } else {
685                                            this.litSearch!.setPercent("tracing htrace failed, please check your config ", -1);
686                                        }
687                                        this.freshConfigMenuDisable(false);
688                                        this.freshMenuDisable(false)
689                                        this.buttonDisable(false);
690                                    });
691                                });
692                            })
693                        } catch (e) {
694                            this.traceCommand!.show = false;
695                            this.freshMenuDisable(false)
696                            this.freshConfigMenuDisable(false)
697                            this.buttonDisable(false);
698                        }
699                    } else {
700                        this.sp!.search = true;
701                        this.litSearch!.clear();
702                        this.litSearch!.setPercent("please kill other hdc-server !", -1);
703                    }
704                }
705            );
706        }
707
708    }
709
710    private isSuccess(traceResult: string): number {
711        if (traceResult.indexOf("CreateSession FAIL") != -1) {
712            return 1;
713        } else if (traceResult.indexOf("Signal") != -1) {
714            return 2;
715        } else if (traceResult.indexOf("The device is abnormal") != -1) {
716            return -1
717        } else {
718            return 0;
719        }
720    }
721
722    private makeRequest = () => {
723        let request = this.createSessionRequest();
724        let hasMonitorMemory = false;
725        let hasSamps = false;
726        if (this.probesConfig!.traceConfig.length > 0) {
727            if (this.probesConfig!.traceConfig.find(value => {
728                return value != "FPS" && value != "AbilityMonitor" && value != "HiSystemEvent"
729            })) {
730                request.pluginConfigs.push(this.createHtracePluginConfig())
731            }
732            if (this.probesConfig!.traceConfig.indexOf("FPS") != -1) {
733                request.pluginConfigs.push(this.createFpsPluginConfig())
734            }
735            if (this.probesConfig!.traceConfig.indexOf("AbilityMonitor") != -1) {
736                hasMonitorMemory = true;
737                this.createMonitorPlugin(this, request);
738            }
739            if (this.probesConfig!.traceConfig.indexOf("HiSystemEvent") != -1) {
740                request.pluginConfigs.push(this.createHiSystemEventPluginConfig())
741            }
742        }
743        let reportingFrequency: number;
744        if (this.recordSetting!.maxDur > 20) {
745            reportingFrequency = 5
746        } else {
747            reportingFrequency = 2
748        }
749        if (this.spVmTracker!.startSamp && this.spVmTracker!.process != "") {
750            hasSamps = true;
751        }
752        if (this.probesConfig!.memoryConfig.length > 0 || hasMonitorMemory || hasSamps) {
753            request.pluginConfigs.push(this.createMemoryPluginConfig(reportingFrequency,this.probesConfig!.memoryConfig.length > 0, hasMonitorMemory, hasSamps))
754        }
755        if (this.spAllocations!.appProcess != "") {
756            request.pluginConfigs.push(this.createNativePluginConfig(reportingFrequency))
757        }
758        if (this.spRecordPerf!.startSamp) {
759            request.pluginConfigs.push(this.createHiperConfig(reportingFrequency))
760        }
761        if (this.spFileSystem!.startRecord) {
762            request.pluginConfigs.push(this.createSystemConfig(reportingFrequency))
763        }
764        if (this.spSdkConfig!.startSamp && this.spSdkConfig!.getPlugName() != "") {
765            request.pluginConfigs.push(this.createSdkConfig(reportingFrequency))
766        }
767        return request;
768    }
769
770    private createSessionRequest() {
771        let bufferConfig: ProfilerSessionConfigBufferConfig = {
772            pages: this.recordSetting!.bufferSize * 256,
773            policy: ProfilerSessionConfigBufferConfigPolicy.RECYCLE
774        }
775        let sessionConfig: ProfilerSessionConfig = {
776            buffers: [bufferConfig],
777            sessionMode: ProfilerSessionConfigMode.OFFLINE,
778            resultFile: this.recordSetting!.output,
779            resultMaxSize: 0,
780            sampleDuration: this.recordSetting!.maxDur * 1000,
781            keepAliveTime: 0
782        }
783        let request: CreateSessionRequest = {
784            requestId: 1,
785            sessionConfig: sessionConfig,
786            pluginConfigs: []
787        }
788        return request;
789    }
790
791    private createMonitorPlugin(that: this, request: CreateSessionRequest) {
792        let processPlugin = that.createProcessPlugin();
793        let cpuPlugin = that.createCpuPlugin();
794        let diskIoPlugin = that.createDiskIOPlugin();
795        let netWorkPlugin = that.createNetworkPlugin();
796        request.pluginConfigs.push(processPlugin)
797        request.pluginConfigs.push(cpuPlugin)
798        request.pluginConfigs.push(diskIoPlugin)
799        request.pluginConfigs.push(netWorkPlugin)
800    }
801
802    private createNetworkPlugin() {
803        let netWorkConfig: NetworkConfig = {
804            testFile: "/data/local/tmp/"
805        }
806        let netWorkPlugin: ProfilerPluginConfig<NetworkConfig> = {
807            pluginName: "network-plugin",
808            sampleInterval: 1000,
809            configData: netWorkConfig
810        }
811        return netWorkPlugin;
812    }
813
814    private createDiskIOPlugin() {
815        let diskIoConfig: DiskioConfig = {
816            reportIoStats: "IO_REPORT"
817        }
818        let diskIoPlugin: ProfilerPluginConfig<DiskioConfig> = {
819            pluginName: "diskio-plugin",
820            sampleInterval: 1000,
821            configData: diskIoConfig
822        }
823        return diskIoPlugin;
824    }
825
826    private createCpuPlugin() {
827        let cpuConfig: CpuConfig = {
828            pid: 0,
829            reportProcessInfo: true
830        }
831        let cpuPlugin: ProfilerPluginConfig<CpuConfig> = {
832            pluginName: "cpu-plugin",
833            sampleInterval: 1000,
834            configData: cpuConfig
835        }
836        return cpuPlugin;
837    }
838
839    private createProcessPlugin() {
840        let processConfig: ProcessConfig = {
841            report_process_tree: true,
842            report_cpu: true,
843            report_diskio: true,
844            report_pss: true,
845        }
846        let processPlugin: ProfilerPluginConfig<ProcessConfig> = {
847            pluginName: "process-plugin",
848            sampleInterval: 1000,
849            configData: processConfig
850        }
851        return processPlugin;
852    }
853
854    createTraceEvents(traceConfig: Array<string>): Array<string> {
855        let traceEvents = new Set<string>();
856        traceConfig.forEach(config => {
857                switch (config) {
858                    case "Scheduling details":
859                        this.schedulingEvents.forEach((eve: string) => {
860                            traceEvents.add(eve)
861                        });
862                        break;
863                    case "CPU Frequency and idle states":
864                        this.cpuFreqEvents.forEach((eve: string) => {
865                            traceEvents.add(eve)
866                        });
867                        break;
868                    case "High frequency memory":
869                        this.highFrequencyEvents.forEach((eve: string) => {
870                            traceEvents.add(eve)
871                        });
872                        break;
873                    case "Advanced ftrace config":
874                        this.advancedConfigEvents.forEach((eve: string) => {
875                            traceEvents.add(eve)
876                        });
877                        break;
878                    case "Syscalls":
879                        this.sysCallsEvents.forEach((eve: string) => {
880                            traceEvents.add(eve)
881                        });
882                        break;
883                    case "Board voltages & frequency":
884                        this.powerEvents.forEach((eve: string) => {
885                            traceEvents.add(eve)
886                        });
887                        break;
888                }
889            }
890        )
891        let ftraceEventsArray: string[] = [];
892        info("traceEvents length is: ", traceEvents.size)
893        for (const ftraceEvent of traceEvents) {
894            ftraceEventsArray.push(ftraceEvent)
895        }
896        return ftraceEventsArray
897    }
898
899    initHtml(): string {
900        return `
901        <style>
902        :host{
903            display: block;
904            height: 100%;
905            width: 100%;
906            background-color: var(--dark-background5,#F6F6F6);
907        }
908        .container {
909            background-color: var(--dark-background5,#F6F6F6);
910            height:100%;
911        }
912
913        .header {
914            padding-top: 30px;
915            padding-bottom: 20px;
916            background-color: var(--dark-background3,#FFFFFF);
917            width: 100%;
918        }
919
920        .span-col-2{
921             margin-left: 20px;
922             display: flex;
923             align-items: center
924        }
925
926        .header-right {
927           display: flex;
928           margin-left: auto;
929           margin-right: 5%;
930        }
931        .header-des{
932          font-family: PingFangSC-Regular;
933          font-size: 1em;
934          color:  #999999;
935          text-align: left;
936          font-weight: 400;
937        }
938
939        .target {
940           opacity: 0.9;
941           font-family: Helvetica;
942           font-size: 14px;
943           color: var(--dark-color2,#000000);
944           line-height: 16px;
945           font-weight: 400;
946           white-space:nowrap;
947           align-self: center;
948        }
949
950        .select{
951           width: 300px;
952           height: 32px;
953           margin-left: 14px;
954           margin-right: 24px;
955           background: var(--dark-background1,#ffffff);
956           border: 1px solid var(--dark-color1,#4D4D4D);
957           border-radius: 16px;
958           opacity: 0.6;
959           font-family: Helvetica;
960           font-size: 14px;
961           color: var(--dark-color1,#000000);
962           text-align: center;
963           line-height: 20px;
964           font-weight: 400;
965           padding: 5px 10px 5px 10px;
966           -webkit-appearance: none;
967           background: url('img/down.png') no-repeat 96% center;
968        }
969        .body{
970            width: 90%;
971            height:80vh;
972            margin-left: 3%;
973            margin-top: 2%;
974            margin-bottom: 2%;
975            display: grid;
976            grid-template-columns: min-content  1fr;
977            background-color: var(--dark-background3,#FFFFFF);
978            border-radius: 16px 16px 16px 16px;
979        }
980
981        .menugroup{
982           height: 100%;
983           background: var(--dark-background3,#FFFFFF);
984        }
985        .menuitem{
986          background: var(--dark-background3,#FFFFFF);
987        }
988        .content{
989          background: var(--dark-background3,#FFFFFF);
990          border-style: none none none solid;
991          border-width: 1px;
992          border-color: rgba(166,164,164,0.2);
993          border-radius: 0px 16px 16px 0px;
994        }
995        :host([show_hint]) #hint {
996            display: block
997        }
998        #hint {
999           display: none;
1000        }
1001
1002        </style>
1003        <div class="container">
1004         <div class="header">
1005           <div style="display: flex;margin-bottom: 24px;margin-left:20px;">
1006             <span class="target">Target Platform:</span>
1007               <select class="select" id = "device-select">
1008               </select>
1009              <lit-button style="width: 180px"class="add" height="32px" width="164px" color="#0A59F7" font_size="14px" border="1px solid #0A59F7"
1010              padding="0 0 0 12px" justify_content="left" icon="add" margin_icon="0 10px 0 8px">Add HDC Device</lit-button>
1011              <div class="header-right">
1012              <lit-button class="record" height="32px" width="96px" font_size="14px" justify_content="center" color="#FFFFFF"
1013              border_radius="16px" back='#0A59F7'>Record</lit-button>
1014              </div>
1015             </div>
1016              <div class="span-col-2" >
1017                 <span class="header-des" id="hint">It looks like you didn't add any probes. Please add at least one</span>
1018              </div>
1019         </div>
1020
1021         <div class="body">
1022            <lit-main-menu-group class="menugroup" id= "menu-group" title="" nocollapsed radius></lit-main-menu-group>
1023            <div id="app-content" class="content">
1024            </div>
1025         </div>
1026        </div>
1027        `;
1028    }
1029
1030    private createHilogConfig(probesConfig: SpProbesConfig, reportingFrequency: number) {
1031        let hilogConfig: HilogConfig = {
1032            deviceType: Type.HI3516,
1033            logLevel: levelFromJSON(probesConfig.hilogConfig[0]),
1034            needClear: true
1035        }
1036        let hilogConfigProfilerPluginConfig: ProfilerPluginConfig<HilogConfig> = {
1037            pluginName: "hilog-plugin",
1038            sampleInterval: reportingFrequency * 1000,
1039            configData: hilogConfig,
1040        }
1041        return hilogConfigProfilerPluginConfig;
1042    }
1043
1044    private createHiperConfig(reportingFrequency: number) {
1045        let perfConfig = this.spRecordPerf!.getPerfConfig();
1046        let recordArgs = "";
1047        recordArgs = recordArgs + "-f " + perfConfig?.frequency;
1048        if (perfConfig?.process && !perfConfig?.process.includes("ALL") && perfConfig?.process.length > 0) {
1049            recordArgs = recordArgs + " -p " + perfConfig?.process;
1050        } else {
1051            recordArgs = recordArgs + " -a ";
1052        }
1053        if (perfConfig?.cpu && !perfConfig?.cpu.includes("ALL") && perfConfig?.cpu.length > 0) {
1054            recordArgs = recordArgs + " -c " + perfConfig?.cpu;
1055        }
1056        if (perfConfig?.cpuPercent != 0) {
1057            recordArgs = recordArgs + " --cpu-limit " + perfConfig?.cpuPercent;
1058        }
1059        if (perfConfig?.eventList && !perfConfig?.eventList.includes("NONE") && perfConfig?.eventList.length > 0) {
1060            recordArgs = recordArgs + " -e " + perfConfig?.eventList;
1061            if (perfConfig?.isOffCpu) {
1062                recordArgs = recordArgs + ",sched:sched_waking";
1063            }
1064        } else {
1065            recordArgs = recordArgs + " -e hw-cpu-cycles"
1066            if (perfConfig?.isOffCpu) {
1067                recordArgs = recordArgs + ",sched:sched_waking";
1068            }
1069        }
1070        if (perfConfig?.callStack != "none") {
1071            recordArgs = recordArgs + " --call-stack " + perfConfig?.callStack
1072        }
1073
1074        if (perfConfig?.branch != "none") {
1075            recordArgs = recordArgs + " -j " + perfConfig?.branch
1076        }
1077
1078        if (perfConfig?.clockType) {
1079            recordArgs = recordArgs + " --clockid " + perfConfig?.clockType
1080        }
1081
1082        if (perfConfig?.isOffCpu) {
1083            recordArgs = recordArgs + " --offcpu"
1084        }
1085
1086        if (perfConfig?.noInherit) {
1087            recordArgs = recordArgs + " --no-inherit"
1088        }
1089
1090        if (perfConfig?.mmap) {
1091            recordArgs = recordArgs + " -m " + perfConfig.mmap;
1092        }
1093        info("record config Args is: ", recordArgs)
1094        let hiPerf: HiperfPluginConfig = {
1095            isRoot: false,
1096            outfileName: "/data/local/tmp/perf.data",
1097            recordArgs: recordArgs
1098        }
1099        let hiPerfPluginConfig: ProfilerPluginConfig<HiperfPluginConfig> = {
1100            pluginName: "hiperf-plugin",
1101            sampleInterval: reportingFrequency * 1000,
1102            configData: hiPerf,
1103        }
1104        return hiPerfPluginConfig;
1105    }
1106
1107    private createSystemConfig(reportingFrequency: number) {
1108        let systemConfig = this.spFileSystem!.getSystemConfig();
1109        let recordArgs = "hiebpf";
1110        if (this.spFileSystem?.startFileSystem && this.spFileSystem?.startVirtualMemory) {
1111            recordArgs += " --events fs,ptrace "
1112        } else if (this.spFileSystem?.startFileSystem) {
1113            recordArgs += " --events fs "
1114        } else if (this.spFileSystem?.startVirtualMemory) {
1115            recordArgs += " --events ptrace "
1116        }
1117        recordArgs += "--duration " + this.recordSetting?.maxDur
1118        if (systemConfig?.process && !systemConfig?.process.includes("ALL") && systemConfig?.process.length > 0) {
1119            recordArgs = recordArgs + " --pids " + systemConfig?.process;
1120        }
1121        let systemPluginConfig: FileSystemConfig = {
1122            cmdLine: recordArgs,
1123            outfileName: "/data/local/tmp/ebpf.data",
1124        }
1125        let ebpfPluginConfig: ProfilerPluginConfig<FileSystemConfig> = {
1126            pluginName: "hiebpf-plugin",
1127            sampleInterval: 1000,
1128            configData: systemPluginConfig,
1129        }
1130        return ebpfPluginConfig;
1131    }
1132
1133    private createNativePluginConfig(reportingFrequency: number) {
1134        let appProcess = this.spAllocations!.appProcess;
1135        let re = /^[0-9]+.?[0-9]*/;
1136        let pid = 0;
1137        let processName = "";
1138        let processId = "";
1139        if (appProcess.indexOf("(") != -1) {
1140            processId = appProcess.slice(appProcess.lastIndexOf("(") + 1, appProcess.lastIndexOf(")"))
1141        } else {
1142            processId = appProcess;
1143        }
1144        if (re.test(processId)) {
1145            pid = Number(processId);
1146        } else {
1147            processName = appProcess;
1148        }
1149        let nativeConfig: NativeHookConfig = {
1150            pid: pid,
1151            saveFile: false,
1152            fileName: "",
1153            filterSize: this.spAllocations!.filter,
1154            smbPages: this.spAllocations!.shared,
1155            maxStackDepth: this.spAllocations!.unwind,
1156            processName: processName,
1157            mallocFreeMatchingInterval: 1000,
1158            mallocFreeMatchingCnt: 1000,
1159            stringCompressed: true,
1160            fpUnwind: this.spAllocations!.fp_unwind
1161        }
1162        let nativePluginConfig: ProfilerPluginConfig<NativeHookConfig> = {
1163            pluginName: "nativehook",
1164            sampleInterval: reportingFrequency * 1000,
1165            configData: nativeConfig,
1166        }
1167        return nativePluginConfig;
1168    }
1169
1170    private createMemoryPluginConfig(reportingFrequency: number, hasmemoryConfig: boolean, hasMonitorMemory: boolean, hasSmaps: boolean) {
1171        let memoryconfig: MemoryConfig = {
1172            reportProcessTree: false,
1173            reportSysmemMemInfo: false,
1174            sysMeminfoCounters: [],
1175            reportSysmemVmemInfo: false,
1176            sysVmeminfoCounters: [],
1177            reportProcessMemInfo: false,
1178            reportAppMemInfo: false,
1179            reportAppMemByMemoryService: false,
1180            pid: []
1181        }
1182        if (hasmemoryConfig || hasMonitorMemory) {
1183            memoryconfig.reportProcessTree = true;
1184            memoryconfig.reportSysmemMemInfo = true;
1185            memoryconfig.reportSysmemVmemInfo = true;
1186            memoryconfig.reportProcessMemInfo = true;
1187        }
1188        if (hasSmaps) {
1189            memoryconfig.reportSmapsMemInfo = true
1190            let pid = Number(this.spVmTracker?.process);
1191            memoryconfig.pid.push(pid)
1192        }
1193        if (hasMonitorMemory) {
1194            SpRecordTrace.ABALITY_MEM_INFO.forEach(va => {
1195                memoryconfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
1196            })
1197        }
1198        this.probesConfig!.memoryConfig.forEach(value => {
1199            if (value.indexOf("Kernel meminfo") != -1) {
1200                if (hasMonitorMemory) {
1201                    memoryconfig.sysMeminfoCounters = [];
1202                }
1203                SpRecordTrace.MEM_INFO.forEach(va => {
1204                    memoryconfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
1205                })
1206            }
1207            if (value.indexOf("Virtual memory stats") != -1) {
1208                SpRecordTrace.VMEM_INFO.forEach((me => {
1209                    memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me))
1210                }))
1211                SpRecordTrace.VMEM_INFO_SECOND.forEach((me => {
1212                    memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me))
1213                }))
1214                SpRecordTrace.VMEM_INFO_THIRD.forEach((me => {
1215                    memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me))
1216                }))
1217            }
1218        })
1219        let profilerPluginConfig: ProfilerPluginConfig<MemoryConfig> = {
1220            pluginName: "memory-plugin",
1221            sampleInterval: reportingFrequency * 1000,
1222            configData: memoryconfig,
1223        }
1224        return profilerPluginConfig;
1225    }
1226
1227    private createFpsPluginConfig() {
1228        let fpsConfig: FpsConfig = {
1229            reportFps: true
1230        }
1231        let fpsPlugin: ProfilerPluginConfig<FpsConfig> = {
1232            pluginName: "hidump-plugin",
1233            sampleInterval: 1000,
1234            configData: fpsConfig
1235        }
1236        return fpsPlugin;
1237    }
1238
1239    private createHiSystemEventPluginConfig() {
1240        let hiSystemEventConfig: HiSystemEventConfig = {
1241            msg: ''
1242        }
1243        let hiSystemEventPlugin: ProfilerPluginConfig<HiSystemEventConfig> = {
1244            pluginName: "hisysevent-plugin",
1245            sampleInterval: 1000,
1246            configData: hiSystemEventConfig
1247        }
1248        return hiSystemEventPlugin;
1249    }
1250
1251    private createHtracePluginConfig() {
1252        let tracePluginConfig: TracePluginConfig = {
1253            ftraceEvents: this.createTraceEvents(this.probesConfig!.traceConfig),
1254            hitraceCategories: [],
1255            hitraceApps: [],
1256            bufferSizeKb: 2048,
1257            flushIntervalMs: 1000,
1258            flushThresholdKb: 4096,
1259            parseKsyms: true,
1260            clock: "mono",
1261            tracePeriodMs: 200,
1262            rawDataPrefix: "",
1263            traceDurationMs: 0,
1264            debugOn: false,
1265            hitraceTime: this.recordSetting!.maxDur
1266        }
1267        if (this.probesConfig!.traceEvents.length > 0) {
1268            tracePluginConfig.hitraceCategories = this.probesConfig!.traceEvents
1269        }
1270        let htraceProfilerPluginConfig: ProfilerPluginConfig<TracePluginConfig> = {
1271            pluginName: "ftrace-plugin",
1272            sampleInterval: 1000,
1273            configData: tracePluginConfig
1274        }
1275        return htraceProfilerPluginConfig;
1276    }
1277
1278    private createSdkConfig(reportingFrequency: number) {
1279        let gpuConfig = this.spSdkConfig!.getGpuConfig();
1280        let gpuPluginConfig: ProfilerPluginConfig<any> = {
1281            pluginName: this.spSdkConfig!.getPlugName(),
1282            sampleInterval: this.spSdkConfig!.getSampleInterval(),
1283            configData: gpuConfig,
1284        }
1285        return gpuPluginConfig;
1286    }
1287
1288
1289    freshConfigMenuDisable(disable: boolean) {
1290        let querySelectors = this.shadowRoot?.querySelectorAll<LitMainMenuItem>('lit-main-menu-item')
1291        querySelectors!.forEach(item => {
1292            if (disable) {
1293                item.style.pointerEvents = 'none'
1294                this.traceCommand!.show = true;
1295            } else {
1296                item.style.pointerEvents = 'auto'
1297                this.traceCommand!.show = false;
1298            }
1299            item.disabled = disable;
1300        })
1301    }
1302
1303    public startRefreshDeviceList() {
1304        if (this.refreshDeviceTimer == null) {
1305            this.refreshDeviceTimer = setInterval(() => {
1306                this.refreshDeviceList();
1307            }, 5000)
1308        }
1309    }
1310
1311    buttonDisable(disable: boolean) {
1312        if (disable) {
1313            this.recordButton!.style.pointerEvents = 'none';
1314            this.addButton!.style.pointerEvents = 'none';
1315            this.deviceSelect!.style.pointerEvents = 'none';
1316        } else {
1317            this.recordButton!.style.pointerEvents = 'auto';
1318            this.addButton!.style.pointerEvents = 'auto';
1319            this.deviceSelect!.style.pointerEvents = 'auto';
1320        }
1321    }
1322
1323    freshMenuItemsStatus(currentValue: string) {
1324        let litMainMenuGroup = this.shadowRoot?.querySelector<LitMainMenuGroup>('lit-main-menu-group');
1325        let litMainMenuItemNodeListOf = litMainMenuGroup!.querySelectorAll<LitMainMenuItem>('lit-main-menu-item');
1326        litMainMenuItemNodeListOf.forEach(item =>{
1327            item.back = item.title == currentValue;
1328        })
1329    }
1330}