• 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,
30  FileSystemConfig,
31  FpsConfig,
32  HilogConfig,
33  HiperfPluginConfig,
34  HiSystemEventConfig,
35  ArkTSConfig,
36  levelFromJSON,
37  MemoryConfig,
38  NativeHookConfig,
39  NetworkConfig,
40  ProcessConfig,
41  ProfilerPluginConfig,
42  ProfilerSessionConfig,
43  ProfilerSessionConfigBufferConfig,
44  ProfilerSessionConfigBufferConfigPolicy,
45  ProfilerSessionConfigMode,
46  sysMeminfoTypeFromJSON,
47  sysVMeminfoTypeFromJSON,
48  TracePluginConfig,
49  Type,
50} from './setting/bean/ProfilerServiceTypes.js';
51import { PluginConvertUtils } from './setting/utils/PluginConvertUtils.js';
52import { SpAllocations } from './setting/SpAllocations.js';
53import { SpRecordPerf } from './setting/SpRecordPerf.js';
54import { HdcDeviceManager } from '../../hdc/HdcDeviceManager.js';
55import { LitButton } from '../../base-ui/button/LitButton.js';
56import { SpApplication } from '../SpApplication.js';
57import { LitSearch } from './trace/search/Search.js';
58import { LitProgressBar } from '../../base-ui/progress-bar/LitProgressBar.js';
59import { info, log } from '../../log/Log.js';
60import { CmdConstant } from '../../command/CmdConstant.js';
61import { Cmd } from '../../command/Cmd.js';
62import { SpFileSystem } from './setting/SpFileSystem.js';
63import { SpSdkConfig } from './setting/SpSdkConfig.js';
64import { SpVmTracker } from './setting/SpVmTracker.js';
65import { SpHisysEvent } from './setting/SpHisysEvent.js';
66import { SpRecordTemplate } from './setting/SpRecordTemplate.js';
67import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js';
68import { SpArkTs } from './setting/SpArkTs.js';
69
70@element('sp-record-trace')
71export class SpRecordTrace extends BaseElement {
72  public static serialNumber: string = '';
73  public static selectVersion: string | null;
74  // 1GB
75  public static MaxFileSize: number = 1024 * 1024 * 1024;
76  public static isVscode = false;
77  public static stopRecord = false;
78  static supportVersions = ['3.2', '4.0'];
79
80  set record_template(re: boolean) {
81    if (re) {
82      this.setAttribute('record_template', '');
83    } else {
84      this.removeAttribute('record_template');
85    }
86  }
87
88  get record_template(): boolean {
89    return this.hasAttribute('record_template');
90  }
91
92  set vs(vs: boolean) {
93    if (vs) {
94      SpRecordTrace.isVscode = true;
95      this.setAttribute('vs', '');
96    } else {
97      SpRecordTrace.isVscode = false;
98      this.removeAttribute('vs');
99    }
100  }
101
102  get vs(): boolean {
103    return this.hasAttribute('vs');
104  }
105
106  static MEM_INFO = [
107    'MEMINFO_ACTIVE',
108    'MEMINFO_ACTIVE_ANON',
109    'MEMINFO_ACTIVE_FILE',
110    'MEMINFO_ANON_PAGES',
111    'MEMINFO_BUFFERS',
112    'MEMINFO_CACHED',
113    'MEMINFO_CMA_FREE',
114    'MEMINFO_CMA_TOTAL',
115    'MEMINFO_COMMIT_LIMIT',
116    'MEMINFO_COMMITED_AS',
117    'MEMINFO_DIRTY',
118    'MEMINFO_INACTIVE',
119    'MEMINFO_INACTIVE_ANON',
120    'MEMINFO_INACTIVE_FILE',
121    'MEMINFO_KERNEL_STACK',
122    'MEMINFO_MAPPED',
123    'MEMINFO_MEM_AVAILABLE',
124    'MEMINFO_MEM_FREE',
125    'MEMINFO_MEM_TOTAL',
126    'MEMINFO_MLOCKED',
127    'MEMINFO_PAGE_TABLES',
128    'MEMINFO_SHMEM',
129    'MEMINFO_SLAB',
130    'MEMINFO_SLAB_RECLAIMABLE',
131    'MEMINFO_SLAB_UNRECLAIMABLE',
132    'MEMINFO_SWAP_CACHED',
133    'MEMINFO_SWAP_FREE',
134    'MEMINFO_SWAP_TOTAL',
135    'MEMINFO_UNEVICTABLE',
136    'MEMINFO_VMALLOC_CHUNK',
137    'MEMINFO_VMALLOC_TOTAL',
138    'MEMINFO_VMALLOC_USED',
139    'MEMINFO_WRITEBACK',
140    'MEMINFO_KERNEL_RECLAIMABLE',
141  ];
142  static VMEM_INFO = [
143    'VMEMINFO_UNSPECIFIED',
144    'VMEMINFO_NR_FREE_PAGES',
145    'VMEMINFO_NR_ALLOC_BATCH',
146    'VMEMINFO_NR_INACTIVE_ANON',
147    'VMEMINFO_NR_ACTIVE_ANON',
148    'VMEMINFO_NR_INACTIVE_FILE',
149    'VMEMINFO_NR_ACTIVE_FILE',
150    'VMEMINFO_NR_UNEVICTABLE',
151    'VMEMINFO_NR_MLOCK',
152    'VMEMINFO_NR_ANON_PAGES',
153    'VMEMINFO_NR_MAPPED',
154    'VMEMINFO_NR_FILE_PAGES',
155    'VMEMINFO_NR_DIRTY',
156    'VMEMINFO_NR_WRITEBACK',
157    'VMEMINFO_NR_SLAB_RECLAIMABLE',
158    'VMEMINFO_NR_SLAB_UNRECLAIMABLE',
159    'VMEMINFO_NR_PAGE_TABLE_PAGES',
160    'VMEMINFO_NR_KERNEL_STACK',
161    'VMEMINFO_NR_OVERHEAD',
162    'VMEMINFO_NR_UNSTABLE',
163    'VMEMINFO_NR_BOUNCE',
164    'VMEMINFO_NR_VMSCAN_WRITE',
165    'VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM',
166    'VMEMINFO_NR_WRITEBACK_TEMP',
167    'VMEMINFO_NR_ISOLATED_ANON',
168    'VMEMINFO_NR_ISOLATED_FILE',
169    'VMEMINFO_NR_SHMEM',
170    'VMEMINFO_NR_DIRTIED',
171    'VMEMINFO_NR_WRITTEN',
172    'VMEMINFO_NR_PAGES_SCANNED',
173    'VMEMINFO_WORKINGSET_REFAULT',
174    'VMEMINFO_WORKINGSET_ACTIVATE',
175    'VMEMINFO_WORKINGSET_NODERECLAIM',
176    'VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES',
177    'VMEMINFO_NR_FREE_CMA',
178    'VMEMINFO_NR_SWAPCACHE',
179    'VMEMINFO_NR_DIRTY_THRESHOLD',
180    'VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD',
181    'VMEMINFO_PGPGIN',
182    'VMEMINFO_PGPGOUT',
183    'VMEMINFO_PGPGOUTCLEAN',
184    'VMEMINFO_PSWPIN',
185    'VMEMINFO_PSWPOUT',
186    'VMEMINFO_PGALLOC_DMA',
187  ];
188  static VMEM_INFO_SECOND = [
189    'VMEMINFO_PGALLOC_NORMAL',
190    'VMEMINFO_PGALLOC_MOVABLE',
191    'VMEMINFO_PGFREE',
192    'VMEMINFO_PGACTIVATE',
193    'VMEMINFO_PGDEACTIVATE',
194    'VMEMINFO_PGFAULT',
195    'VMEMINFO_PGMAJFAULT',
196    'VMEMINFO_PGREFILL_DMA',
197    'VMEMINFO_PGREFILL_NORMAL',
198    'VMEMINFO_PGREFILL_MOVABLE',
199    'VMEMINFO_PGSTEAL_KSWAPD_DMA',
200    'VMEMINFO_PGSTEAL_KSWAPD_NORMAL',
201    'VMEMINFO_PGSTEAL_KSWAPD_MOVABLE',
202    'VMEMINFO_PGSTEAL_DIRECT_DMA',
203    'VMEMINFO_PGSTEAL_DIRECT_NORMAL',
204    'VMEMINFO_PGSTEAL_DIRECT_MOVABLE',
205    'VMEMINFO_PGSCAN_KSWAPD_DMA',
206    'VMEMINFO_PGSCAN_KSWAPD_NORMAL',
207    'VMEMINFO_PGSCAN_KSWAPD_MOVABLE',
208    'VMEMINFO_PGSCAN_DIRECT_DMA',
209    'VMEMINFO_PGSCAN_DIRECT_NORMAL',
210    'VMEMINFO_PGSCAN_DIRECT_MOVABLE',
211    'VMEMINFO_PGSCAN_DIRECT_THROTTLE',
212    'VMEMINFO_PGINODESTEAL',
213    'VMEMINFO_SLABS_SCANNED',
214    'VMEMINFO_KSWAPD_INODESTEAL',
215    'VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY',
216    'VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY',
217    'VMEMINFO_PAGEOUTRUN',
218    'VMEMINFO_ALLOCSTALL',
219    'VMEMINFO_PGROTATED',
220    'VMEMINFO_DROP_PAGECACHE',
221    'VMEMINFO_DROP_SLAB',
222    'VMEMINFO_PGMIGRATE_SUCCESS',
223    'VMEMINFO_PGMIGRATE_FAIL',
224    'VMEMINFO_COMPACT_MIGRATE_SCANNED',
225    'VMEMINFO_COMPACT_FREE_SCANNED',
226    'VMEMINFO_COMPACT_ISOLATED',
227    'VMEMINFO_COMPACT_STALL',
228    'VMEMINFO_COMPACT_FAIL',
229    'VMEMINFO_COMPACT_SUCCESS',
230    'VMEMINFO_COMPACT_DAEMON_WAKE',
231    'VMEMINFO_UNEVICTABLE_PGS_CULLED',
232    'VMEMINFO_UNEVICTABLE_PGS_SCANNED',
233    'VMEMINFO_UNEVICTABLE_PGS_RESCUED',
234    'VMEMINFO_UNEVICTABLE_PGS_MLOCKED',
235    'VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED',
236  ];
237  static VMEM_INFO_THIRD = [
238    'VMEMINFO_UNEVICTABLE_PGS_CLEARED',
239    'VMEMINFO_UNEVICTABLE_PGS_STRANDED',
240    'VMEMINFO_NR_ZSPAGES',
241    'VMEMINFO_NR_ION_HEAP',
242    'VMEMINFO_NR_GPU_HEAP',
243    'VMEMINFO_ALLOCSTALL_DMA',
244    'VMEMINFO_ALLOCSTALL_MOVABLE',
245    'VMEMINFO_ALLOCSTALL_NORMAL',
246    'VMEMINFO_COMPACT_DAEMON_FREE_SCANNED',
247    'VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED',
248    'VMEMINFO_NR_FASTRPC',
249    'VMEMINFO_NR_INDIRECTLY_RECLAIMABLE',
250    'VMEMINFO_NR_ION_HEAP_POOL',
251    'VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE',
252    'VMEMINFO_NR_SHADOW_CALL_STACK_BYTES',
253    'VMEMINFO_NR_SHMEM_HUGEPAGES',
254    'VMEMINFO_NR_SHMEM_PMDMAPPED',
255    'VMEMINFO_NR_UNRECLAIMABLE_PAGES',
256    'VMEMINFO_NR_ZONE_ACTIVE_ANON',
257    'VMEMINFO_NR_ZONE_ACTIVE_FILE',
258    'VMEMINFO_NR_ZONE_INACTIVE_ANON',
259    'VMEMINFO_NR_ZONE_INACTIVE_FILE',
260    'VMEMINFO_NR_ZONE_UNEVICTABLE',
261    'VMEMINFO_NR_ZONE_WRITE_PENDING',
262    'VMEMINFO_OOM_KILL',
263    'VMEMINFO_PGLAZYFREE',
264    'VMEMINFO_PGLAZYFREED',
265    'VMEMINFO_PGREFILL',
266    'VMEMINFO_PGSCAN_DIRECT',
267    'VMEMINFO_PGSCAN_KSWAPD',
268    'VMEMINFO_PGSKIP_DMA',
269    'VMEMINFO_PGSKIP_MOVABLE',
270    'VMEMINFO_PGSKIP_NORMAL',
271    'VMEMINFO_PGSTEAL_DIRECT',
272    'VMEMINFO_PGSTEAL_KSWAPD',
273    'VMEMINFO_SWAP_RA',
274    'VMEMINFO_SWAP_RA_HIT',
275    'VMEMINFO_WORKINGSET_RESTORE',
276  ];
277  // sys.mem.total   sys.mem.free sys.mem.buffers sys.mem.cached  sys.mem.shmem  sys.mem.slab  sys.mem.swap.total
278  // sys.mem.swap.free sys.mem.mapped  sys.mem.vmalloc.used  sys.mem.page.tables  sys.mem.kernel.stack
279  // sys.mem.active sys.mem.inactive  sys.mem.unevictable  sys.mem.vmalloc.total sys.mem.slab.unreclaimable
280  // sys.mem.cma.total sys.mem.cma.free
281  static ABALITY_MEM_INFO = [
282    'MEMINFO_MEM_TOTAL',
283    'MEMINFO_MEM_FREE',
284    'MEMINFO_BUFFERS',
285    'MEMINFO_CACHED',
286    'MEMINFO_SHMEM',
287    'MEMINFO_SLAB',
288    'MEMINFO_SWAP_TOTAL',
289    'MEMINFO_SWAP_FREE',
290    'MEMINFO_MAPPED',
291    'MEMINFO_VMALLOC_USED',
292    'MEMINFO_PAGE_TABLES',
293    'MEMINFO_KERNEL_STACK',
294    'MEMINFO_ACTIVE',
295    'MEMINFO_INACTIVE',
296    'MEMINFO_UNEVICTABLE',
297    'MEMINFO_VMALLOC_TOTAL',
298    'MEMINFO_SLAB_UNRECLAIMABLE',
299    'MEMINFO_CMA_TOTAL',
300    'MEMINFO_CMA_FREE',
301    'MEMINFO_KERNEL_RECLAIMABLE',
302  ];
303
304  schedulingEvents = [
305    'sched/sched_switch',
306    'power/suspend_resume',
307    'sched/sched_wakeup',
308    'sched/sched_wakeup_new',
309    'sched/sched_waking',
310    'sched/sched_process_exit',
311    'sched/sched_process_free',
312    'task/task_newtask',
313    'task/task_rename',
314  ];
315  powerEvents = [
316    'regulator/regulator_set_voltage',
317    'regulator/regulator_set_voltage_complete',
318    'power/clock_enable',
319    'power/clock_disable',
320    'power/clock_set_rate',
321    'power/suspend_resume',
322  ];
323  cpuFreqEvents = ['power/cpu_frequency', 'power/cpu_idle', 'power/suspend_resume'];
324  sysCallsEvents = ['raw_syscalls/sys_enter', 'raw_syscalls/sys_exit'];
325  highFrequencyEvents = [
326    'mm_event/mm_event_record',
327    'kmem/rss_stat',
328    'ion/ion_stat',
329    'dmabuf_heap/dma_heap_stat',
330    'kmem/ion_heap_grow',
331    'kmem/ion_heap_shrink',
332  ];
333  advancedConfigEvents = [
334    'sched/sched_switch',
335    'sched/sched_wakeup',
336    'sched/sched_wakeup_new',
337    'sched/sched_waking',
338    'sched/sched_process_exit',
339    'sched/sched_process_free',
340    'irq/irq_handler_entry',
341    'irq/irq_handler_exit',
342    'irq/softirq_entry',
343    'irq/softirq_exit',
344    'irq/softirq_raise',
345    'power/clock_disable',
346    'power/clock_enable',
347    'power/clock_set_rate',
348    'power/cpu_frequency',
349    'power/cpu_idle',
350    'clk/clk_disable',
351    'clk/clk_disable_complete',
352    'clk/clk_enable',
353    'clk/clk_enable_complete',
354    'clk/clk_set_rate',
355    'clk/clk_set_rate_complete',
356    'binder/binder_transaction',
357    'binder/binder_transaction_alloc_buf',
358    'binder/binder_transaction_received',
359    'binder/binder_lock',
360    'binder/binder_locked',
361    'binder/binder_unlock',
362    'workqueue/workqueue_execute_start',
363    'workqueue/workqueue_execute_end',
364    'oom/oom_score_adj_update',
365    'ftrace/print',
366  ];
367  private _menuItems: Array<MenuItem> | undefined;
368
369  public deviceSelect: HTMLSelectElement | undefined;
370  public deviceVersion: HTMLSelectElement | undefined;
371  private recordButtonText: HTMLSpanElement | undefined;
372
373  private recordButton: LitButton | undefined;
374  private sp: SpApplication | undefined;
375  private progressEL: LitProgressBar | undefined;
376  private litSearch: LitSearch | undefined;
377  private addButton: LitButton | undefined | null;
378  private disconnectButton: LitButton | undefined | null;
379
380  private recordSetting: SpRecordSetting | undefined;
381  private probesConfig: SpProbesConfig | undefined;
382  private traceCommand: SpTraceCommand | undefined;
383  private spAllocations: SpAllocations | undefined;
384  private spRecordPerf: SpRecordPerf | undefined;
385  private spFileSystem: SpFileSystem | undefined;
386  private spSdkConfig: SpSdkConfig | undefined;
387  private spVmTracker: SpVmTracker | undefined;
388  private spHisysEvent: SpHisysEvent | undefined;
389  private spRecordTemplate: SpRecordTemplate | undefined;
390  private spArkTs: SpArkTs | undefined;
391
392  private menuGroup: LitMainMenuGroup | undefined | null;
393  private appContent: HTMLElement | undefined | null;
394  private record = 'Record';
395  private stop = 'StopCmd';
396
397  compareArray(devs: Array<string>): boolean {
398    let clearFlag: boolean = false;
399    if (devs.length != this.deviceSelect!.options.length) {
400      clearFlag = true;
401    } else {
402      let optionArray = new Array();
403      for (let i = 0 ; i < this.deviceSelect!.options.length ; i++) {
404        optionArray.push(this.deviceSelect!.options[i].value);
405      }
406      devs.forEach((value) => {
407        if (optionArray.indexOf(value) == -1) {
408          clearFlag = true;
409        }
410      });
411    }
412    return clearFlag;
413  }
414
415  refreshDeviceList(): void {
416    if (this.vs) {
417      Cmd.execHdcCmd(CmdConstant.CMD_HDC_DEVICES, (res: string) => {
418        let devs: string[] = res.trim().replace(/\r\n/g, '\r').replace(/\n/g, '\r').split(/\r/);
419        if (devs.length == 1 && devs[0].indexOf('Empty') != -1) {
420          this.deviceSelect!.innerHTML = '';
421          return;
422        }
423        let clearFlag = this.compareArray(devs);
424        if (clearFlag) {
425          this.deviceSelect!.innerHTML = '';
426          if (devs.length == 0) {
427            this.recordButton!.hidden = true;
428            this.disconnectButton!.hidden = true;
429          }
430          for (let i = 0 ; i < devs.length ; i++) {
431            let dev = devs[i];
432            let option = document.createElement('option');
433            option.className = 'select';
434            option.textContent = dev;
435            this.deviceSelect!.appendChild(option);
436            if (i == 0) {
437              option.selected = true;
438              this.recordButton!.hidden = false;
439              this.disconnectButton!.hidden = false;
440              SpRecordTrace.serialNumber = option.value;
441            }
442          }
443        }
444      });
445    } else {
446      this.deviceSelect!.innerHTML = '';
447      // @ts-ignore
448      HdcDeviceManager.getDevices().then((devs: USBDevice[]) => {
449        if (devs.length == 0) {
450          this.recordButton!.hidden = true;
451          this.disconnectButton!.hidden = true;
452        }
453        for (let len = 0 ; len < devs.length ; len++) {
454          let dev = devs[len];
455          let option = document.createElement('option');
456          option.className = 'select';
457          if (typeof dev.serialNumber === 'string') {
458            option.value = dev.serialNumber;
459          }
460          option.textContent = dev!.serialNumber ? dev!.serialNumber!.toString() : 'hdc Device';
461          this.deviceSelect!.appendChild(option);
462          if (len == 0) {
463            option.selected = true;
464            this.recordButton!.hidden = false;
465            this.disconnectButton!.hidden = false;
466            SpRecordTrace.serialNumber = option.value;
467            HdcDeviceManager.connect(option.value).then((result) => {
468              if (result) {
469                HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_VERSION, false).then((version) => {
470                  let deviceVersionItem = SpRecordTrace.supportVersions.filter((item) => version.indexOf(item) != -1);
471                  if (deviceVersionItem.length > 0) {
472                    SpRecordTrace.selectVersion = deviceVersionItem[0];
473                    this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
474                  } else {
475                    SpRecordTrace.selectVersion = SpRecordTrace.supportVersions[0];
476                    this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
477                  }
478                  this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
479                    PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
480                    this.recordSetting!.output,
481                    this.recordSetting!.maxDur
482                  );
483                });
484              } else {
485                SpRecordTrace.selectVersion = SpRecordTrace.supportVersions[0];
486                this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
487                let cmdTxt = PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false)
488                this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
489                  cmdTxt,
490                  this.recordSetting!.output,
491                  this.recordSetting!.maxDur
492                );
493              }
494            });
495          }
496        }
497      });
498    }
499  }
500
501  freshMenuDisable(disable: boolean): void {
502    let mainMenu = this.sp!.shadowRoot?.querySelector('#main-menu') as LitMainMenu;
503    mainMenu.menus?.forEach((men) => {
504      men.children.forEach((child) => {
505        // @ts-ignore
506        child.disabled = disable;
507      });
508    });
509    mainMenu.menus = mainMenu.menus;
510  }
511
512  set showHint(bool: boolean) {
513    if (bool) {
514      if (this.hasAttribute('show_hint')) {
515        this.removeAttribute('show_hint');
516        setTimeout(() => {
517          this.setAttribute('show_hint', '');
518        }, 200);
519      } else {
520        this.setAttribute('show_hint', '');
521      }
522    } else {
523      this.removeAttribute('show_hint');
524    }
525  }
526
527  private refreshDeviceTimer: number | undefined;
528
529  initElements(): void {
530    let parentElement = this.parentNode as HTMLElement;
531    parentElement.style.overflow = 'hidden';
532    this.recordSetting = new SpRecordSetting();
533    this.probesConfig = new SpProbesConfig();
534    this.traceCommand = new SpTraceCommand();
535    this.spAllocations = new SpAllocations();
536    this.spRecordPerf = new SpRecordPerf();
537    this.spFileSystem = new SpFileSystem();
538    this.spSdkConfig = new SpSdkConfig();
539    this.spVmTracker = new SpVmTracker();
540    this.spHisysEvent = new SpHisysEvent();
541    this.spArkTs = new SpArkTs();
542    this.spRecordTemplate = new SpRecordTemplate(this);
543    this.addButton = this.shadowRoot?.querySelector<LitButton>('.add');
544    this.addButton!.addEventListener('click', () => {
545      if (this.vs) {
546        this.refreshDeviceList();
547      } else {
548        // @ts-ignore
549        HdcDeviceManager.findDevice().then((usbDevices) => {
550          log(usbDevices);
551          this.refreshDeviceList();
552        });
553      }
554    });
555    this.deviceSelect = this.shadowRoot?.querySelector('#device-select') as HTMLSelectElement;
556    this.deviceVersion = this.shadowRoot?.querySelector('#device-version') as HTMLSelectElement;
557    this.deviceSelect!.onchange = (): void => {
558      if (this.deviceSelect!.options.length > 0) {
559        this.recordButton!.hidden = false;
560        this.disconnectButton!.hidden = false;
561      } else {
562        this.recordButton!.hidden = true;
563        this.disconnectButton!.hidden = true;
564      }
565      let deviceItem = this.deviceSelect!.options[this.deviceSelect!.selectedIndex];
566      let value = deviceItem.value;
567      SpRecordTrace.serialNumber = value;
568      if (this.vs) {
569        let cmd = Cmd.formatString(CmdConstant.CMD_GET_VERSION_DEVICES, [SpRecordTrace.serialNumber]);
570        Cmd.execHdcCmd(cmd, (deviceVersion: string) => {
571          this.selectedDevice(deviceVersion);
572          this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
573            PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
574            this.recordSetting!.output,
575            this.recordSetting!.maxDur
576          );
577        });
578      } else {
579        HdcDeviceManager.connect(value).then((result) => {
580          if (result) {
581            HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_VERSION, true).then((deviceVersion) => {
582              this.selectedDevice(deviceVersion);
583              this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
584                PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
585                this.recordSetting!.output,
586                this.recordSetting!.maxDur
587              );
588            });
589          } else {
590            SpRecordTrace.selectVersion = SpRecordTrace.supportVersions[0];
591            this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
592            this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
593              PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
594              this.recordSetting!.output,
595              this.recordSetting!.maxDur
596            );
597          }
598        });
599      }
600    };
601    this.deviceVersion.onchange = (): void => {
602      let versionItem = this.deviceVersion!.options[this.deviceVersion!.selectedIndex];
603      SpRecordTrace.selectVersion = versionItem.getAttribute('device-version');
604      this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
605        PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
606        this.recordSetting!.output,
607        this.recordSetting!.maxDur
608      );
609    };
610    this.appendDeviceVersion();
611    // @ts-ignore
612    if (navigator.usb) {
613      // @ts-ignore
614      navigator.usb.addEventListener(
615        'connect',
616        // @ts-ignore
617        (ev: USBConnectionEvent) => {
618          this.usbConnectionListener(ev);
619        }
620      );
621      // @ts-ignore
622      navigator.usb.addEventListener(
623        'disconnect',
624        // @ts-ignore
625        (ev: USBConnectionEvent) => {
626          this.usbDisConnectionListener(ev);
627        }
628      );
629    }
630    this.disconnectButton = this.shadowRoot?.querySelector<LitButton>('.disconnect');
631    this.disconnectButton?.addEventListener('click', (evt) => {
632      let index = this.deviceSelect!.selectedIndex;
633      if (index != -1) {
634        let selectOption = this.deviceSelect!.options[index];
635        let value = selectOption.value;
636        HdcDeviceManager.disConnect(value).then((re) => {
637          this.deviceSelect!.removeChild(selectOption);
638          if (this.deviceSelect!.selectedIndex != -1) {
639            let item = this.deviceSelect!.options[this.deviceSelect!.selectedIndex];
640            SpRecordTrace.serialNumber = item.value;
641          } else {
642            this.recordButton!.hidden = true;
643            this.disconnectButton!.hidden = true;
644            this.sp!.search = false;
645            SpRecordTrace.serialNumber = '';
646          }
647        });
648      }
649    });
650
651    this.recordButton = this.shadowRoot?.querySelector('.record') as LitButton;
652    this.recordButtonText = this.shadowRoot?.querySelector('.record_text') as HTMLSpanElement;
653    this.sp = document.querySelector('sp-application') as SpApplication;
654    this.progressEL = this.sp.shadowRoot?.querySelector('.progress') as LitProgressBar;
655    this.litSearch = this.sp.shadowRoot?.querySelector('#lit-record-search') as LitSearch;
656    if (this.deviceSelect!.options && this.deviceSelect!.options.length > 0) {
657      this.disconnectButton!.hidden = false;
658      this.recordButton!.hidden = false;
659    } else {
660      this.disconnectButton!.hidden = true;
661      this.recordButton!.hidden = true;
662    }
663    this.recordButton!.addEventListener('click', () => {
664      if (this.recordButtonText!.textContent == this.record) {
665        this.recordButtonListener();
666      } else {
667        this.stopRecordListener();
668      }
669    });
670    this.spRecordPerf!.addEventListener('addProbe', () => {
671      this.showHint = false;
672    });
673    this.spAllocations!.addEventListener('addProbe', () => {
674      this.showHint = false;
675    });
676    this.probesConfig!.addEventListener('addProbe', () => {
677      this.showHint = false;
678    });
679    this.spRecordTemplate!.addEventListener('addProbe', () => {
680      this.showHint = false;
681    });
682    this.menuGroup = this.shadowRoot?.querySelector('#menu-group') as LitMainMenuGroup;
683    this.appContent = this.shadowRoot?.querySelector('#app-content') as HTMLElement;
684    if (this.record_template) {
685      this.appContent.append(this.spRecordTemplate);
686    } else {
687      this.appContent.append(this.recordSetting);
688    }
689    this.initMenuItems();
690  }
691
692  private selectedDevice(deviceVersion: string): void {
693    let deviceVersionItem = SpRecordTrace.supportVersions.filter((item) => deviceVersion.indexOf(item) != -1);
694    if (deviceVersionItem.length > 0) {
695      SpRecordTrace.selectVersion = deviceVersionItem[0];
696    } else {
697      SpRecordTrace.selectVersion = SpRecordTrace.supportVersions[0];
698    }
699    this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
700  }
701
702  private appendDeviceVersion(): void {
703    SpRecordTrace.supportVersions.forEach((supportVersion) => {
704      let option = document.createElement('option');
705      option.className = 'select';
706      option.textContent = `OpenHarmony-${ supportVersion }`;
707      option.setAttribute('device-version', supportVersion);
708      this.deviceVersion!.append(option);
709    });
710  }
711
712  private setDeviceVersionSelect(selected: string): void {
713    let children = this.deviceVersion!.children;
714    for (let i = 0 ; i < children.length ; i++) {
715      let child = children[i] as HTMLOptionElement;
716      if (child.getAttribute('device-version') === selected) {
717        child.selected = true;
718        break;
719      }
720    }
721  }
722
723  stopRecordListener(): void {
724    this.recordButtonText!.textContent = 'Record';
725    if (this.vs) {
726      let cmd = Cmd.formatString(CmdConstant.CMS_HDC_STOP, [SpRecordTrace.serialNumber]);
727      Cmd.execHdcCmd(cmd, (res: string) => {
728        this.freshMenuDisable(false);
729        this.freshConfigMenuDisable(false);
730        this.progressEL!.loading = false;
731        this.sp!.search = false;
732        this.litSearch!.clear();
733        this.addButton!.style.pointerEvents = 'auto';
734        this.deviceSelect!.style.pointerEvents = 'auto';
735        this.disconnectButton!.style.pointerEvents = 'auto';
736        this.deviceVersion!.style.pointerEvents = 'auto';
737      });
738    } else {
739      let selectedOption = this.deviceSelect!.options[this.deviceSelect!.selectedIndex] as HTMLOptionElement;
740      HdcDeviceManager.connect(selectedOption.value).then((result) => {
741        if (result) {
742          this.freshMenuDisable(false);
743          this.freshConfigMenuDisable(false);
744          try {
745            this.progressEL!.loading = false;
746            this.sp!.search = false;
747            this.litSearch!.clear();
748            this.disconnectButton!.style.pointerEvents = 'auto';
749            this.addButton!.style.pointerEvents = 'auto';
750            this.deviceSelect!.style.pointerEvents = 'auto';
751            this.deviceVersion!.style.pointerEvents = 'auto';
752            SpRecordTrace.stopRecord = true;
753            HdcDeviceManager.stopHiprofiler(CmdConstant.CMS_STOP, true).then((result) => {});
754          } catch (exception) {
755            log(exception);
756          }
757        }
758      });
759    }
760  }
761
762  private initMenuItems(): void {
763    let that = this;
764    if (this.record_template) {
765      this._menuItems = [
766        {
767          title: 'Record setting',
768          icon: 'properties',
769          fileChoose: false,
770          clickHandler: function (event: InputEvent): void {
771            that.appContent!.innerHTML = '';
772            that.appContent!.append(that.recordSetting!);
773            that.freshMenuItemsStatus('Record setting');
774          },
775        },
776        {
777          title: 'Trace template',
778          icon: 'realIntentionBulb',
779          clickHandler: function (ev: InputEvent): void {
780            that.appContent!.innerHTML = '';
781            that.appContent!.append(that.spRecordTemplate!);
782            that.freshMenuItemsStatus('Trace template');
783          },
784        },
785        {
786          title: 'Trace command',
787          icon: 'dbsetbreakpoint',
788          fileChoose: false,
789          clickHandler: function (ev: InputEvent): void {
790            that.appContent!.innerHTML = '';
791            that.appContent!.append(that.traceCommand!);
792            that.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
793              PluginConvertUtils.BeanToCmdTxt(that.makeRequest(), false),
794              that.recordSetting!.output,
795              that.recordSetting!.maxDur
796            );
797            that.freshMenuItemsStatus('Trace command');
798          },
799        },
800      ];
801    } else {
802      this._menuItems = [
803        {
804          title: 'Record setting',
805          icon: 'properties',
806          fileChoose: false,
807          clickHandler: function (ev: InputEvent): void {
808            that.appContent!.innerHTML = '';
809            that.appContent!.append(that.recordSetting!);
810            that.freshMenuItemsStatus('Record setting');
811          },
812        },
813        {
814          title: 'Trace command',
815          icon: 'dbsetbreakpoint',
816          fileChoose: false,
817          clickHandler: function (ev: InputEvent): void {
818            that.freshMenuItemsStatus('Trace command');
819            let request = that.makeRequest();
820            that.appContent!.innerHTML = '';
821            that.appContent!.append(that.traceCommand!);
822            that.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
823              PluginConvertUtils.BeanToCmdTxt(request, false),
824              that.recordSetting!.output,
825              that.recordSetting!.maxDur
826            );
827          },
828        },
829        {
830          title: 'Probes config',
831          icon: 'realIntentionBulb',
832          fileChoose: false,
833          clickHandler: function (ev: InputEvent): void {
834            that.appContent!.innerHTML = '';
835            that.appContent!.append(that.probesConfig!);
836            that.freshMenuItemsStatus('Probes config');
837          },
838        },
839        {
840          title: 'Native Memory',
841          icon: 'externaltools',
842          fileChoose: false,
843          clickHandler: function (ev: InputEvent): void {
844            that.appContent!.innerHTML = '';
845            that.appContent!.append(that.spAllocations!);
846            that.freshMenuItemsStatus('Native Memory');
847          },
848        },
849        {
850          title: 'Hiperf',
851          icon: 'realIntentionBulb',
852          fileChoose: false,
853          clickHandler: function (ev: InputEvent): void {
854            that.appContent!.innerHTML = '';
855            that.appContent!.append(that.spRecordPerf!);
856            that.freshMenuItemsStatus('Hiperf');
857          },
858        },
859        {
860          title: 'eBPF Config',
861          icon: 'file-config',
862          fileChoose: false,
863          clickHandler: function (ev: InputEvent): void {
864            that.appContent!.innerHTML = '';
865            that.appContent!.append(that.spFileSystem!);
866            that.freshMenuItemsStatus('eBPF Config');
867          },
868        },
869        {
870          title: 'VM Tracker',
871          icon: 'vm-tracker',
872          fileChoose: false,
873          clickHandler: function (ev: InputEvent): void {
874            that.appContent!.innerHTML = '';
875            that.appContent!.append(that.spVmTracker!);
876            that.freshMenuItemsStatus('VM Tracker');
877          },
878        },
879        {
880          title: 'HiSystemEvent',
881          icon: 'externaltools',
882          fileChoose: false,
883          clickHandler: function (ev: InputEvent): void {
884            that.appContent!.innerHTML = '';
885            that.appContent!.append(that.spHisysEvent!);
886            that.freshMenuItemsStatus('HiSystemEvent');
887          },
888        },
889        {
890          title: 'Ark Ts',
891          icon: 'file-config',
892          fileChoose: false,
893          clickHandler: function (ev: InputEvent): void {
894            that.appContent!.innerHTML = '';
895            that.appContent!.append(that.spArkTs!);
896            that.freshMenuItemsStatus('Ark Ts');
897          },
898        },
899        {
900          title: 'SDK Config',
901          icon: 'file-config',
902          fileChoose: false,
903          clickHandler: function (ev: InputEvent): void {
904            that.appContent!.innerHTML = '';
905            that.appContent!.append(that.spSdkConfig!);
906            that.freshMenuItemsStatus('SDK Config');
907          },
908        },
909      ];
910    }
911
912    this._menuItems?.forEach((item) => {
913      let th = new LitMainMenuItem();
914      th.setAttribute('icon', item.icon || '');
915      th.setAttribute('title', item.title || '');
916      th.style.height = '60px';
917      th.style.fontFamily = 'Helvetica-Bold';
918      th.style.fontSize = '16px';
919      th.style.lineHeight = '28px';
920      th.style.fontWeight = '700';
921      th.removeAttribute('file');
922      th.addEventListener('click', (e) => {
923        if (item.clickHandler) {
924          item.clickHandler(item);
925        }
926      });
927      this.menuGroup!.appendChild(th);
928    });
929  }
930  // @ts-ignore
931  usbConnectionListener(event: USBConnectionEvent): void {
932    if (event.isTrusted) {
933      this.recordButton!.hidden = false;
934      this.disconnectButton!.hidden = false;
935      // @ts-ignore
936      let usbDevice: USBDevice = event.device;
937      let option = document.createElement('option');
938      option.className = 'select';
939      if (typeof usbDevice.serialNumber === 'string') {
940        option.value = usbDevice.serialNumber;
941      }
942      option.selected = true;
943      option.textContent = usbDevice!.serialNumber ? usbDevice!.serialNumber.replace(/"/g, '') : 'hdc Device';
944      this.deviceSelect!.appendChild(option);
945      SpRecordTrace.serialNumber = option.value;
946    }
947  }
948
949  // @ts-ignore
950  usbDisConnectionListener(event: USBConnectionEvent): void {
951    // @ts-ignore
952    let disConnectDevice: USBDevice = event.device;
953    for (let index = 0 ; index < this.deviceSelect!.children.length ; index++) {
954      let option = this.deviceSelect!.children[index] as HTMLOptionElement;
955      if (option.value == disConnectDevice.serialNumber) {
956        let optValue = option.value;
957        HdcDeviceManager.disConnect(optValue).then(() => {});
958        this.deviceSelect!.removeChild(option);
959        if (SpRecordTrace.serialNumber == optValue) {
960          let options = this.deviceSelect!.options;
961          if (options.length > 0) {
962            let selectedOpt = options[this.deviceSelect!.selectedIndex];
963            SpRecordTrace.serialNumber = selectedOpt.value;
964          } else {
965            this.recordButton!.hidden = true;
966            this.disconnectButton!.hidden = true;
967            SpRecordTrace.serialNumber = '';
968          }
969        }
970      }
971    }
972  }
973
974  recordButtonListener(): void {
975    SpRecordTrace.stopRecord = false;
976    let request = this.makeRequest();
977    if (request.pluginConfigs.length == 0) {
978      this.showHint = true;
979      return;
980    } else {
981      this.showHint = false;
982    }
983    let traceCommandStr = PluginConvertUtils.createHdcCmd(
984      PluginConvertUtils.BeanToCmdTxt(request, false),
985      this.recordSetting!.output,
986      this.recordSetting!.maxDur
987    );
988    let pluginList: Array<string> = [];
989    request.pluginConfigs.forEach((pluginConfig) => {
990      pluginList.push(pluginConfig.pluginName);
991    });
992    SpStatisticsHttpUtil.addOrdinaryVisitAction({
993      action: 'config_page',
994      event: 'online_record',
995      eventData: {
996        plugin: pluginList,
997      },
998    });
999    let selectedOption = this.deviceSelect!.options[this.deviceSelect!.selectedIndex] as HTMLOptionElement;
1000    if (selectedOption) {
1001      SpRecordTrace.serialNumber = selectedOption.value;
1002    } else {
1003      this.sp!.search = true;
1004      this.litSearch!.clear();
1005      this.progressEL!.loading = false;
1006      this.litSearch!.setPercent('please connect device', -2);
1007    }
1008
1009    if (this.vs) {
1010      this.appContent!.innerHTML = '';
1011      this.appContent!.append(this.traceCommand!);
1012      this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
1013        PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
1014        this.recordSetting!.output,
1015        this.recordSetting!.maxDur
1016      );
1017      this.freshMenuItemsStatus('Trace command');
1018      Cmd.execHdcCmd(Cmd.formatString(CmdConstant.CMS_HDC_STOP, [SpRecordTrace.serialNumber]), (stopRes: string) => {
1019        let cmd = Cmd.formatString(CmdConstant.CMD_MOUNT_DEVICES, [SpRecordTrace.serialNumber]);
1020        Cmd.execHdcCmd(cmd, (res: string) => {
1021          this.sp!.search = true;
1022          this.progressEL!.loading = true;
1023          this.litSearch!.clear();
1024          this.litSearch!.setPercent('tracing  ' + this.recordSetting!.maxDur * 1000 + 'ms', -1);
1025          this.initRecordUIState();
1026          this.recordButtonText!.textContent = this.stop;
1027          Cmd.execHdcTraceCmd(traceCommandStr, SpRecordTrace.serialNumber, (traceResult: string) => {
1028            if (traceResult.indexOf('DestroySession done') != -1) {
1029              this.litSearch!.setPercent('tracing htrace down', -1);
1030              let cmd = Cmd.formatString(CmdConstant.CMD_FIEL_RECV_DEVICES, [
1031                SpRecordTrace.serialNumber,
1032                this.recordSetting!.output,
1033              ]);
1034              Cmd.execFileRecv(cmd, this.recordSetting!.output, (rt: ArrayBuffer) => {
1035                this.litSearch!.setPercent('downloading Hitrace file ', 101);
1036                let fileName = this.recordSetting!.output.substring(this.recordSetting!.output.lastIndexOf('/') + 1);
1037                let file = new File([rt], fileName);
1038                let main = this!.parentNode!.parentNode!.querySelector('lit-main-menu') as LitMainMenu;
1039                let children = main.menus as Array<MenuGroup>;
1040                let child = children[0].children as Array<MenuItem>;
1041                let fileHandler = child[0].fileHandler;
1042                if (fileHandler && !SpRecordTrace.stopRecord) {
1043                  this.recordButtonText!.textContent = this.record;
1044                  this.freshMenuDisable(false);
1045                  this.freshConfigMenuDisable(false);
1046                  fileHandler({ detail: file });
1047                } else {
1048                  SpRecordTrace.stopRecord = false;
1049                }
1050              });
1051            } else {
1052              this.litSearch!.setPercent('tracing htrace failed, please check your config ', -2);
1053              this.recordButtonText!.textContent = this.record;
1054              this.freshMenuDisable(false);
1055              this.freshConfigMenuDisable(false);
1056              this.progressEL!.loading = false;
1057            }
1058            this.buttonDisable(false);
1059          });
1060        });
1061      });
1062    } else {
1063      HdcDeviceManager.connect(selectedOption.value).then((result) => {
1064        log('result is ' + result);
1065        if (result) {
1066          this.appContent!.innerHTML = '';
1067          this.appContent!.append(this.traceCommand!);
1068          let config = this.makeRequest();
1069          this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
1070            PluginConvertUtils.BeanToCmdTxt(config, false),
1071            this.recordSetting!.output,
1072            this.recordSetting!.maxDur
1073          );
1074          this.freshMenuItemsStatus('Trace command');
1075          try {
1076            HdcDeviceManager.stopHiprofiler(CmdConstant.CMS_STOP, true).then(() => {
1077              HdcDeviceManager.shellResultAsString(CmdConstant.CMD_MOUNT, true).then(() => {
1078                this.sp!.search = true;
1079                this.progressEL!.loading = true;
1080                this.litSearch!.clear();
1081                this.litSearch!.setPercent('tracing  ' + this.recordSetting!.maxDur * 1000 + 'ms', -1);
1082                this.buttonDisable(true);
1083                this.freshMenuDisable(true);
1084                this.freshConfigMenuDisable(true);
1085                HdcDeviceManager.shellResultAsString(CmdConstant.CMD_SHELL + traceCommandStr, false).then(
1086                  (traceResult) => {
1087                    let re = this.isSuccess(traceResult);
1088                    if (re == 0) {
1089                      this.litSearch!.setPercent('tracing htrace down', -1);
1090                      HdcDeviceManager.shellResultAsString(
1091                        CmdConstant.CMD_TRACE_FILE_SIZE + this.recordSetting!.output,
1092                        false
1093                      ).then((traceFileSize) => {
1094                        if (traceFileSize.indexOf('No such') != -1) {
1095                          this.litSearch!.setPercent('No such file or directory', -2);
1096                          this.buttonDisable(false);
1097                          this.freshConfigMenuDisable(false);
1098                          this.freshMenuDisable(false);
1099                        } else if (Number(traceFileSize) <= SpRecordTrace.MaxFileSize) {
1100                          HdcDeviceManager.fileRecv(this.recordSetting!.output, (perNumber: number) => {
1101                            this.litSearch!.setPercent('downloading Hitrace file ', perNumber);
1102                          }).then((pullRes) => {
1103                            this.litSearch!.setPercent('downloading Hitrace file ', 101);
1104                            pullRes.arrayBuffer().then((buffer) => {
1105                              let fileName = this.recordSetting!.output.substring(
1106                                this.recordSetting!.output.lastIndexOf('/') + 1
1107                              );
1108                              let file = new File([buffer], fileName);
1109                              let main = this!.parentNode!.parentNode!.querySelector('lit-main-menu') as LitMainMenu;
1110                              let children = main.menus as Array<MenuGroup>;
1111                              let child = children[0].children as Array<MenuItem>;
1112                              let fileHandler = child[0].fileHandler;
1113                              if (fileHandler && !SpRecordTrace.stopRecord) {
1114                                this.freshConfigMenuDisable(false);
1115                                this.freshMenuDisable(false);
1116                                this.buttonDisable(false);
1117                                fileHandler({
1118                                  detail: file,
1119                                });
1120                              } else {
1121                                SpRecordTrace.stopRecord = false;
1122                              }
1123                            });
1124                          });
1125                        } else {
1126                          this.recordButtonText!.textContent = this.record;
1127                          this.litSearch!.setPercent('htrace file is too big', -2);
1128                          this.buttonDisable(false);
1129                          this.freshConfigMenuDisable(false);
1130                          this.freshMenuDisable(false);
1131                        }
1132                      });
1133                    } else if (re == 2) {
1134                      this.litSearch!.setPercent('stop tracing htrace ', -1);
1135                      this.freshConfigMenuDisable(false);
1136                      this.freshMenuDisable(false);
1137                      this.buttonDisable(false);
1138                    } else if (re == -1) {
1139                      this.litSearch!.setPercent('The device is abnormal', -2);
1140                      this.progressEL!.loading = false;
1141                      this.freshConfigMenuDisable(false);
1142                      this.freshMenuDisable(false);
1143                      this.buttonDisable(false);
1144                    } else {
1145                      this.litSearch!.setPercent('tracing htrace failed, please check your config ', -2);
1146                      this.freshConfigMenuDisable(false);
1147                      this.freshMenuDisable(false);
1148                      this.buttonDisable(false);
1149                    }
1150                  }
1151                );
1152              });
1153            });
1154          } catch (e) {
1155            this.freshMenuDisable(false);
1156            this.freshConfigMenuDisable(false);
1157            this.buttonDisable(false);
1158          }
1159        } else {
1160          this.sp!.search = true;
1161          this.litSearch!.clear();
1162          this.litSearch!.setPercent('please kill other hdc-server !', -2);
1163        }
1164      });
1165    }
1166  }
1167
1168  private initRecordUIState(): void {
1169    this.buttonDisable(true);
1170    this.freshMenuDisable(true);
1171    this.freshConfigMenuDisable(true);
1172  }
1173
1174  private isSuccess(traceResult: string): number {
1175    if (traceResult.indexOf('CreateSession FAIL') != -1 || traceResult.indexOf('failed') != -1) {
1176      return 1;
1177    } else if (traceResult.indexOf('Signal') != -1) {
1178      return 2;
1179    } else if (traceResult.indexOf('The device is abnormal') != -1) {
1180      return -1;
1181    } else {
1182      return 0;
1183    }
1184  }
1185
1186  private makeRequest = (): CreateSessionRequest => {
1187    let request = this.createSessionRequest();
1188    if (this.record_template) {
1189      let templateConfigs = this.spRecordTemplate?.getTemplateConfig();
1190      templateConfigs?.forEach((config) => {
1191        request.pluginConfigs.push(config);
1192      });
1193    } else {
1194      let hasMonitorMemory = false;
1195      let hasSamps = false;
1196      if (this.probesConfig!.traceConfig.length > 0) {
1197        if (
1198          this.probesConfig!.traceConfig.find((value) => {
1199            return value != 'FPS';
1200          })
1201        ) {
1202          request.pluginConfigs.push(this.createHtracePluginConfig());
1203        }
1204        if (this.probesConfig!.traceConfig.indexOf('FPS') != -1) {
1205          request.pluginConfigs.push(this.createFpsPluginConfig());
1206        }
1207      }
1208      if (this.probesConfig!.recordAbility) {
1209        hasMonitorMemory = true;
1210        this.createMonitorPlugin(this, request);
1211      }
1212      let reportingFrequency: number;
1213      if (this.recordSetting!.maxDur > 20) {
1214        reportingFrequency = 5;
1215      } else {
1216        reportingFrequency = 2;
1217      }
1218      if (this.spVmTracker!.startSamp && this.spVmTracker!.process != '') {
1219        hasSamps = true;
1220      }
1221      if (this.probesConfig!.memoryConfig.length > 0 || hasMonitorMemory || hasSamps) {
1222        request.pluginConfigs.push(
1223          this.createMemoryPluginConfig(
1224            reportingFrequency,
1225            this.probesConfig!.memoryConfig.length > 0,
1226            hasMonitorMemory,
1227            hasSamps
1228          )
1229        );
1230      }
1231      if (this.spAllocations!.appProcess != '') {
1232        request.pluginConfigs.push(this.createNativePluginConfig(reportingFrequency));
1233      }
1234      if (this.spRecordPerf!.startSamp) {
1235        request.pluginConfigs.push(this.createHiperConfig(reportingFrequency));
1236      }
1237      if (this.spFileSystem!.startRecord) {
1238        request.pluginConfigs.push(this.createSystemConfig());
1239      }
1240      if (this.spSdkConfig!.startSamp && this.spSdkConfig!.getPlugName() != '') {
1241        request.pluginConfigs.push(this.createSdkConfig());
1242      }
1243      if (this.spHisysEvent?.startSamp) {
1244        request.pluginConfigs.push(this.createHiSystemEventPluginConfig(this.spHisysEvent.process));
1245      }
1246      if (this.spArkTs!.process != '' && this.spArkTs!.startSamp) {
1247        request.pluginConfigs.push(this.createArkTsConfig());
1248      }
1249    }
1250    return request;
1251  };
1252
1253  private createSessionRequest(): CreateSessionRequest {
1254    let bufferConfig: ProfilerSessionConfigBufferConfig = {
1255      pages: this.recordSetting!.bufferSize * 256,
1256      policy: ProfilerSessionConfigBufferConfigPolicy.RECYCLE,
1257    };
1258    let sessionConfig: ProfilerSessionConfig = {
1259      buffers: [bufferConfig],
1260      sessionMode: ProfilerSessionConfigMode.OFFLINE,
1261      resultFile: this.recordSetting!.output,
1262      resultMaxSize: 0,
1263      sampleDuration: this.recordSetting!.maxDur * 1000,
1264      keepAliveTime: 0,
1265    };
1266    let request: CreateSessionRequest = {
1267      requestId: 1,
1268      sessionConfig: sessionConfig,
1269      pluginConfigs: [],
1270    };
1271    return request;
1272  }
1273
1274  private createMonitorPlugin(that: this, request: CreateSessionRequest): void {
1275    let processPlugin = that.createProcessPlugin();
1276    let cpuPlugin = that.createCpuPlugin();
1277    let diskIoPlugin = that.createDiskIOPlugin();
1278    let netWorkPlugin = that.createNetworkPlugin();
1279    request.pluginConfigs.push(processPlugin);
1280    request.pluginConfigs.push(cpuPlugin);
1281    request.pluginConfigs.push(diskIoPlugin);
1282    request.pluginConfigs.push(netWorkPlugin);
1283  }
1284
1285  private createNetworkPlugin(): ProfilerPluginConfig<NetworkConfig> {
1286    let netWorkConfig: NetworkConfig = {};
1287    let netWorkPlugin: ProfilerPluginConfig<NetworkConfig> = {
1288      pluginName: 'network-plugin',
1289      sampleInterval: 1000,
1290      configData: netWorkConfig,
1291    };
1292    SpRecordTrace.appendSerialize(netWorkPlugin);
1293    return netWorkPlugin;
1294  }
1295
1296  private createDiskIOPlugin(): ProfilerPluginConfig<DiskioConfig> {
1297    let diskIoConfig: DiskioConfig = {
1298      reportIoStats: 'IO_REPORT',
1299    };
1300    let diskIoPlugin: ProfilerPluginConfig<DiskioConfig> = {
1301      pluginName: 'diskio-plugin',
1302      sampleInterval: 1000,
1303      configData: diskIoConfig,
1304    };
1305    SpRecordTrace.appendSerialize(diskIoPlugin);
1306    return diskIoPlugin;
1307  }
1308
1309  private createCpuPlugin(): ProfilerPluginConfig<CpuConfig> {
1310    let cpuConfig: CpuConfig = {
1311      pid: 0,
1312      reportProcessInfo: true,
1313    };
1314    let cpuPlugin: ProfilerPluginConfig<CpuConfig> = {
1315      pluginName: 'cpu-plugin',
1316      sampleInterval: 1000,
1317      configData: cpuConfig,
1318    };
1319    SpRecordTrace.appendSerialize(cpuPlugin);
1320    return cpuPlugin;
1321  }
1322
1323  private createProcessPlugin(): ProfilerPluginConfig<ProcessConfig> {
1324    let processConfig: ProcessConfig = {
1325      report_process_tree: true,
1326      report_cpu: true,
1327      report_diskio: true,
1328      report_pss: true,
1329    };
1330    let processPlugin: ProfilerPluginConfig<ProcessConfig> = {
1331      pluginName: 'process-plugin',
1332      sampleInterval: 1000,
1333      configData: processConfig,
1334    };
1335    SpRecordTrace.appendSerialize(processPlugin);
1336    return processPlugin;
1337  }
1338
1339  createTraceEvents(traceConfig: Array<string>): Array<string> {
1340    let traceEvents = new Set<string>();
1341    traceConfig.forEach((config) => {
1342      switch (config) {
1343        case 'Scheduling details':
1344          this.schedulingEvents.forEach((eve: string) => {
1345            traceEvents.add(eve);
1346          });
1347          break;
1348        case 'CPU Frequency and idle states':
1349          this.cpuFreqEvents.forEach((eve: string) => {
1350            traceEvents.add(eve);
1351          });
1352          break;
1353        case 'High frequency memory':
1354          this.highFrequencyEvents.forEach((eve: string) => {
1355            traceEvents.add(eve);
1356          });
1357          break;
1358        case 'Advanced ftrace config':
1359          this.advancedConfigEvents.forEach((eve: string) => {
1360            traceEvents.add(eve);
1361          });
1362          break;
1363        case 'Syscalls':
1364          this.sysCallsEvents.forEach((eve: string) => {
1365            traceEvents.add(eve);
1366          });
1367          break;
1368        case 'Board voltages & frequency':
1369          this.powerEvents.forEach((eve: string) => {
1370            traceEvents.add(eve);
1371          });
1372          break;
1373      }
1374    });
1375    let ftraceEventsArray: string[] = [];
1376    info('traceEvents length is: ', traceEvents.size);
1377    for (const ftraceEvent of traceEvents) {
1378      ftraceEventsArray.push(ftraceEvent);
1379    }
1380    return ftraceEventsArray;
1381  }
1382
1383  initHtml(): string {
1384    return `
1385        <style>
1386        :host{
1387            display: block;
1388            height: 100%;
1389            width: 100%;
1390            background-color: var(--dark-background5,#F6F6F6);
1391        }
1392        .container {
1393            background-color: var(--dark-background5,#F6F6F6);
1394            height:100%;
1395        }
1396
1397        .header {
1398            padding-top: 30px;
1399            padding-bottom: 20px;
1400            background-color: var(--dark-background3,#FFFFFF);
1401            width: 100%;
1402        }
1403
1404        .span-col-2{
1405             margin-left: 20px;
1406             display: flex;
1407             align-items: center
1408        }
1409
1410        .header-right {
1411           display: flex;
1412           margin-left: auto;
1413           margin-right: 5%;
1414        }
1415        .header-des{
1416          font-family: PingFangSC-Regular;
1417          font-size: 1em;
1418          color:  #999999;
1419          text-align: left;
1420          font-weight: 400;
1421        }
1422
1423        .target {
1424           opacity: 0.9;
1425           font-family: Helvetica;
1426           font-size: 14px;
1427           color: var(--dark-color2,#000000);
1428           line-height: 16px;
1429           font-weight: 400;
1430           white-space:nowrap;
1431           align-self: center;
1432        }
1433
1434        .select{
1435           width: 300px;
1436           height: 32px;
1437           margin-left: 14px;
1438           margin-right: 10px;
1439           border: 1px solid var(--dark-color1,#4D4D4D);
1440           background: var(--dark-background1,#ffffff);
1441           font-size: 14px;
1442           border-radius: 16px;
1443           opacity: 0.6;
1444           -webkit-appearance: none;
1445           font-family: Helvetica;
1446           color: var(--dark-color1,#000000);
1447           line-height: 20px;
1448           font-weight: 400;
1449           padding: 5px 10px 5px 10px;
1450           text-align: center;
1451           background: url('img/down.png') no-repeat 96% center;
1452        }
1453        .device_version {
1454           width: 200px;
1455           height: 32px;
1456           margin-left: 5px;
1457           margin-right: 24px;
1458           background: var(--dark-background1,#ffffff);
1459           border: 1px solid var(--dark-color1,#4D4D4D);
1460           border-radius: 16px;
1461           opacity: 0.6;
1462           font-family: Helvetica;
1463           font-size: 14px;
1464           color: var(--dark-color1,#000000);
1465           text-align: center;
1466           line-height: 20px;
1467           font-weight: 400;
1468           padding: 5px 10px 5px 10px;
1469           -webkit-appearance: none;
1470           background: url('img/down.png') no-repeat 96% center;
1471        }
1472        .body{
1473            width: 90%;
1474            height:80vh;
1475            margin-left: 3%;
1476            margin-top: 2%;
1477            margin-bottom: 2%;
1478            display: grid;
1479            grid-template-columns: min-content  1fr;
1480            background-color: var(--dark-background3,#FFFFFF);
1481            border-radius: 16px 16px 16px 16px;
1482        }
1483
1484        .menugroup{
1485           height: 100%;
1486           background: var(--dark-background3,#FFFFFF);
1487        }
1488        .menuitem{
1489          background: var(--dark-background3,#FFFFFF);
1490        }
1491        .content{
1492          background: var(--dark-background3,#FFFFFF);
1493          border-style: none none none solid;
1494          border-width: 1px;
1495          border-color: rgba(166,164,164,0.2);
1496          border-radius: 0px 16px 16px 0px;
1497        }
1498        :host([show_hint]) #hint {
1499            color: #DB5860;
1500            position: absolute;
1501            left:1%;
1502            animation: textRoll 5s ease-in-out 0s backwards;
1503            white-space: nowrap;
1504            display: block;
1505            font-weight: 700;
1506        }
1507        #hint {
1508           display: none;
1509        }
1510
1511        @keyframes textRoll {
1512            0% {
1513                left: 1%;
1514
1515            }
1516            100% {
1517                left:100%;
1518            }
1519        }
1520
1521        </style>
1522        <div class="container">
1523         <div class="header">
1524           <div style="display: flex;margin-bottom: 24px;margin-left:20px;">
1525             <span class="target">Target Platform:</span>
1526               <select class="select" id = "device-select">
1527               </select>
1528               <select class="device_version" id = "device-version">
1529               </select>
1530              <lit-button style="width: 180px" class="add" height="32px" width="164px" color="#0A59F7" font_size="14px" border="1px solid #0A59F7"
1531              padding="0 0 0 12px" justify_content="left" icon="add" margin_icon="0 10px 0 8px">Add HDC Device</lit-button>
1532              <div class="header-right">
1533              <lit-button class="disconnect" style="margin-right: 30px" height="32px" width="96px" font_size="14px" justify_content="center" color="#FFFFFF"
1534              border_radius="16px" back='#0A59F7' opacity="0.6" border="0 solid">Disconnect</lit-button>
1535              <lit-button class="record" height="32px" width="96px" font_size="14px" justify_content="center" color="#FFFFFF"
1536              border_radius="16px" back='#0A59F7' opacity="0.6" border="0 solid"><span class="record_text">Record</span></lit-button>
1537              </div>
1538             </div>
1539              <div class="span-col-2" >
1540                 <span class="header-des" id="hint">It looks like you didn't add any probes. Please add at least one</span>
1541              </div>
1542         </div>
1543
1544         <div class="body">
1545            <lit-main-menu-group class="menugroup" id= "menu-group" title="" nocollapsed radius></lit-main-menu-group>
1546            <div id="app-content" class="content">
1547            </div>
1548         </div>
1549        </div>
1550        `;
1551  }
1552
1553  private createHilogConfig(probesConfig: SpProbesConfig, reportingFrequency: number): ProfilerPluginConfig<HilogConfig> {
1554    let hilogConfig: HilogConfig = {
1555      deviceType: Type.HI3516,
1556      logLevel: levelFromJSON(probesConfig.hilogConfig[0]),
1557      needClear: true,
1558    };
1559    let hilogConfigProfilerPluginConfig: ProfilerPluginConfig<HilogConfig> = {
1560      pluginName: 'hilog-plugin',
1561      sampleInterval: reportingFrequency * 1000,
1562      configData: hilogConfig,
1563    };
1564    SpRecordTrace.appendSerialize(hilogConfigProfilerPluginConfig);
1565    return hilogConfigProfilerPluginConfig;
1566  }
1567
1568  private isNumber(str: string): boolean {
1569    return !isNaN(Number(str));
1570  }
1571
1572  private createHiperConfig(reportingFrequency: number): ProfilerPluginConfig<HiperfPluginConfig> {
1573    let perfConfig = this.spRecordPerf!.getPerfConfig();
1574    let recordArgs = '';
1575    recordArgs = recordArgs + '-f ' + perfConfig?.frequency;
1576    if (perfConfig?.process && !perfConfig?.process.includes('ALL') && perfConfig?.process.length > 0) {
1577      let process = perfConfig.process;
1578      if (process.indexOf(',') != -1) {
1579        let processIdOrName = process.split(',');
1580        if (this.isNumber(processIdOrName[0])) {
1581          recordArgs = recordArgs + ' -p ' + perfConfig?.process;
1582        } else {
1583          recordArgs = recordArgs + ' --app ' + perfConfig?.process;
1584        }
1585      } else {
1586        if (this.isNumber(process)) {
1587          recordArgs = recordArgs + ' -p ' + perfConfig?.process;
1588        } else {
1589          recordArgs = recordArgs + ' --app ' + perfConfig?.process;
1590        }
1591      }
1592    } else {
1593      recordArgs = recordArgs + ' -a ';
1594    }
1595    if (perfConfig?.cpu && !perfConfig?.cpu.includes('ALL') && perfConfig?.cpu.length > 0) {
1596      recordArgs = recordArgs + ' -c ' + perfConfig?.cpu;
1597    }
1598    if (perfConfig?.cpuPercent != 0) {
1599      recordArgs = recordArgs + ' --cpu-limit ' + perfConfig?.cpuPercent;
1600    }
1601    if (perfConfig?.eventList && !perfConfig?.eventList.includes('NONE') && perfConfig?.eventList.length > 0) {
1602      recordArgs = recordArgs + ' -e ' + perfConfig?.eventList;
1603      if (perfConfig?.isOffCpu) {
1604        recordArgs = recordArgs + ',sched:sched_waking';
1605      }
1606    } else {
1607      recordArgs = recordArgs + ' -e hw-cpu-cycles';
1608      if (perfConfig?.isOffCpu) {
1609        recordArgs = recordArgs + ',sched:sched_waking';
1610      }
1611    }
1612    if (perfConfig?.callStack != 'none') {
1613      recordArgs = recordArgs + ' --call-stack ' + perfConfig?.callStack;
1614    }
1615
1616    if (perfConfig?.branch != 'none') {
1617      recordArgs = recordArgs + ' -j ' + perfConfig?.branch;
1618    }
1619
1620    if (perfConfig?.clockType) {
1621      recordArgs = recordArgs + ' --clockid ' + perfConfig?.clockType;
1622    }
1623
1624    if (perfConfig?.isOffCpu) {
1625      recordArgs = recordArgs + ' --offcpu';
1626    }
1627
1628    if (perfConfig?.noInherit) {
1629      recordArgs = recordArgs + ' --no-inherit';
1630    }
1631
1632    if (perfConfig?.mmap) {
1633      recordArgs = recordArgs + ' -m ' + perfConfig.mmap;
1634    }
1635    info('record config Args is: ', recordArgs);
1636    let hiPerf: HiperfPluginConfig = {
1637      isRoot: false,
1638      outfileName: '/data/local/tmp/perf.data',
1639      recordArgs: recordArgs,
1640    };
1641    let hiPerfPluginConfig: ProfilerPluginConfig<HiperfPluginConfig> = {
1642      pluginName: 'hiperf-plugin',
1643      sampleInterval: reportingFrequency * 1000,
1644      configData: hiPerf,
1645    };
1646    return hiPerfPluginConfig;
1647  }
1648
1649  private createSystemConfig(): ProfilerPluginConfig<FileSystemConfig> {
1650    let systemConfig = this.spFileSystem!.getSystemConfig();
1651    let recordArgs = 'hiebpf';
1652    let recordEvent = [];
1653    if (this.spFileSystem?.startFileSystem) {
1654      recordEvent.push('fs');
1655    }
1656    if (this.spFileSystem?.startVirtualMemory) {
1657      recordEvent.push('ptrace');
1658    }
1659    if (this.spFileSystem?.startIo) {
1660      recordEvent.push('bio');
1661    }
1662    if (recordEvent.length > 0) {
1663      recordArgs += ' --events ' + recordEvent.toString();
1664    }
1665    recordArgs += ' --duration ' + this.recordSetting?.maxDur;
1666    if (systemConfig?.process && !systemConfig?.process.includes('ALL') && systemConfig?.process.length > 0) {
1667      recordArgs = recordArgs + ' --pids ' + systemConfig?.process;
1668    }
1669    recordArgs += ' --max_stack_depth ' + systemConfig?.unWindLevel;
1670    let systemPluginConfig: FileSystemConfig = {
1671      cmdLine: recordArgs,
1672      outfileName: '/data/local/tmp/ebpf.data',
1673    };
1674    let ebpfPluginConfig: ProfilerPluginConfig<FileSystemConfig> = {
1675      pluginName: 'hiebpf-plugin',
1676      sampleInterval: 1000,
1677      configData: systemPluginConfig,
1678    };
1679    return ebpfPluginConfig;
1680  }
1681
1682  private createNativePluginConfig(reportingFrequency: number): ProfilerPluginConfig<NativeHookConfig> {
1683    let appProcess = this.spAllocations!.appProcess;
1684    let re = /^[0-9]+.?[0-9]*/;
1685    let pid = 0;
1686    let processName = '';
1687    let processId = '';
1688    if (this.spAllocations!.startup_mode && Number(SpRecordTrace.selectVersion) >= 4.0) {
1689      processName = appProcess;
1690    } else {
1691      if (appProcess.indexOf('(') != -1) {
1692        processId = appProcess.slice(appProcess.lastIndexOf('(') + 1, appProcess.lastIndexOf(')'));
1693      } else {
1694        processId = appProcess;
1695      }
1696      if (re.test(processId)) {
1697        pid = Number(processId);
1698      } else {
1699        processName = appProcess;
1700      }
1701    }
1702    let nativeConfig: NativeHookConfig = {
1703      pid: pid,
1704      saveFile: false,
1705      fileName: '',
1706      filterSize: this.spAllocations!.filter,
1707      smbPages: this.spAllocations!.shared,
1708      maxStackDepth: this.spAllocations!.unwind,
1709      processName: processName,
1710      stringCompressed: true,
1711      fpUnwind: this.spAllocations!.fp_unwind,
1712      blocked: true,
1713    };
1714    if (Number(SpRecordTrace.selectVersion) >= 4.0) {
1715      nativeConfig.callframeCompress = true;
1716      nativeConfig.recordAccurately = this.spAllocations!.record_accurately;
1717      nativeConfig.offlineSymbolization = this.spAllocations!.offline_symbolization;
1718      if (this.spAllocations!.record_statistics) {
1719        nativeConfig.statisticsInterval = this.spAllocations!.statistics_interval;
1720      }
1721      nativeConfig.startupMode = this.spAllocations!.startup_mode;
1722    }
1723    let nativePluginConfig: ProfilerPluginConfig<NativeHookConfig> = {
1724      pluginName: 'nativehook',
1725      sampleInterval: reportingFrequency * 1000,
1726      configData: nativeConfig,
1727    };
1728    return nativePluginConfig;
1729  }
1730
1731  private createMemoryPluginConfig(
1732    reportingFrequency: number,
1733    hasmemoryConfig: boolean,
1734    hasMonitorMemory: boolean,
1735    hasSmaps: boolean
1736  ): ProfilerPluginConfig<MemoryConfig> {
1737    let memoryconfig: MemoryConfig = {
1738      reportProcessTree: false,
1739      reportSysmemMemInfo: false,
1740      sysMeminfoCounters: [],
1741      reportSysmemVmemInfo: false,
1742      sysVmeminfoCounters: [],
1743      reportProcessMemInfo: false,
1744      reportAppMemInfo: false,
1745      reportAppMemByMemoryService: false,
1746      pid: [],
1747    };
1748    if (hasmemoryConfig || hasMonitorMemory) {
1749      memoryconfig.reportProcessTree = true;
1750      memoryconfig.reportSysmemMemInfo = true;
1751      memoryconfig.reportSysmemVmemInfo = true;
1752      memoryconfig.reportProcessMemInfo = true;
1753    }
1754    if (hasSmaps || hasMonitorMemory){
1755      memoryconfig.reportPurgeableAshmemInfo = true;
1756      memoryconfig.reportDmaMemInfo = true;
1757      memoryconfig.reportGpuMemInfo = true;
1758    }
1759    if (hasSmaps) {
1760      memoryconfig.reportSmapsMemInfo = true;
1761      memoryconfig.reportGpuDumpInfo = true;
1762      let pid = Number(this.spVmTracker?.process);
1763      memoryconfig.pid.push(pid);
1764    }
1765    if (hasMonitorMemory) {
1766      SpRecordTrace.ABALITY_MEM_INFO.forEach((va) => {
1767        memoryconfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
1768      });
1769    }
1770    this.probesConfig!.memoryConfig.forEach((value) => {
1771      if (value.indexOf('Kernel meminfo') != -1) {
1772        if (hasMonitorMemory) {
1773          memoryconfig.sysMeminfoCounters = [];
1774        }
1775        SpRecordTrace.MEM_INFO.forEach((va) => {
1776          memoryconfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
1777        });
1778      }
1779      if (value.indexOf('Virtual memory stats') != -1) {
1780        SpRecordTrace.VMEM_INFO.forEach((me) => {
1781          memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
1782        });
1783        SpRecordTrace.VMEM_INFO_SECOND.forEach((me) => {
1784          memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
1785        });
1786        SpRecordTrace.VMEM_INFO_THIRD.forEach((me) => {
1787          memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
1788        });
1789      }
1790    });
1791    let profilerPluginConfig: ProfilerPluginConfig<MemoryConfig> = {
1792      pluginName: 'memory-plugin',
1793      sampleInterval: reportingFrequency * 1000,
1794      configData: memoryconfig,
1795    };
1796    SpRecordTrace.appendSerialize(profilerPluginConfig);
1797    return profilerPluginConfig;
1798  }
1799
1800  private createArkTsConfig(): ProfilerPluginConfig<ArkTSConfig> {
1801    let process = this.spArkTs!.process;
1802    let re = /^[0-9]+.?[0-9]*/;
1803    let pid = 0;
1804    let processId = '';
1805    if (process.indexOf('(') != -1) {
1806      processId = process.slice(process.lastIndexOf('(') + 1, process.lastIndexOf(')'));
1807    } else {
1808      processId = process;
1809    }
1810    if (re.test(processId)) {
1811      pid = Number(processId);
1812    }
1813    let arkTSConfig: ArkTSConfig = {
1814      pid: pid,
1815      type: this.spArkTs!.radioBoxType,
1816      interval: this.spArkTs!.intervalValue,
1817      capture_numeric_value: this.spArkTs!.grabNumeric,
1818      track_allocations: this.spArkTs!.grabAllocations,
1819      enable_cpu_profiler: this.spArkTs!.grabCpuProfiler,
1820      cpu_profiler_interval: this.spArkTs!.intervalCpuValue,
1821    };
1822    let arkTSPluginConfig: ProfilerPluginConfig<ArkTSConfig> = {
1823      pluginName: 'arkts-plugin',
1824      sampleInterval: 5000,
1825      configData: arkTSConfig,
1826    };
1827
1828    return arkTSPluginConfig;
1829  }
1830
1831  private createFpsPluginConfig(): ProfilerPluginConfig<FpsConfig> {
1832    let fpsConfig: FpsConfig = {
1833      reportFps: true,
1834    };
1835    let fpsPlugin: ProfilerPluginConfig<FpsConfig> = {
1836      pluginName: 'hidump-plugin',
1837      sampleInterval: 1000,
1838      configData: fpsConfig,
1839    };
1840    SpRecordTrace.appendSerialize(fpsPlugin);
1841    return fpsPlugin;
1842  }
1843
1844  private createHiSystemEventPluginConfig(appName: string): ProfilerPluginConfig<HiSystemEventConfig> {
1845    let hiSystemEventConfig: HiSystemEventConfig = {
1846      msg: 'hisysevent-plugin',
1847      processName: appName,
1848    };
1849    let hiSystemEventPlugin: ProfilerPluginConfig<HiSystemEventConfig> = {
1850      pluginName: 'hisysevent-plugin',
1851      configData: hiSystemEventConfig,
1852    };
1853    SpRecordTrace.appendSerialize(hiSystemEventPlugin);
1854    return hiSystemEventPlugin;
1855  }
1856
1857  private createHtracePluginConfig(): ProfilerPluginConfig<TracePluginConfig> {
1858    let tracePluginConfig: TracePluginConfig = {
1859      ftraceEvents: this.createTraceEvents(this.probesConfig!.traceConfig),
1860      hitraceCategories: [],
1861      hitraceApps: [],
1862      bufferSizeKb: this.probesConfig!.ftraceBufferSize,
1863      flushIntervalMs: 1000,
1864      flushThresholdKb: 4096,
1865      parseKsyms: true,
1866      clock: 'boot',
1867      tracePeriodMs: 200,
1868      rawDataPrefix: '',
1869      traceDurationMs: 0,
1870      debugOn: false,
1871      hitraceTime: this.recordSetting!.maxDur,
1872    };
1873    if (this.probesConfig!.traceEvents.length > 0) {
1874      tracePluginConfig.hitraceCategories = this.probesConfig!.traceEvents;
1875    }
1876    let htraceProfilerPluginConfig: ProfilerPluginConfig<TracePluginConfig> = {
1877      pluginName: 'ftrace-plugin',
1878      sampleInterval: 1000,
1879      configData: tracePluginConfig,
1880    };
1881    SpRecordTrace.appendSerialize(htraceProfilerPluginConfig);
1882    return htraceProfilerPluginConfig;
1883  }
1884
1885  static appendSerialize(profilerPluginConfig: ProfilerPluginConfig<{}>): void {
1886    if (Number(SpRecordTrace.selectVersion) >= 4.0) {
1887    }
1888  }
1889
1890  private createSdkConfig(): ProfilerPluginConfig<{}> {
1891    let gpuConfig = this.spSdkConfig!.getGpuConfig();
1892    let gpuPluginConfig: ProfilerPluginConfig<{}> = {
1893      pluginName: this.spSdkConfig!.getPlugName(),
1894      sampleInterval: this.spSdkConfig!.getSampleInterval(),
1895      configData: gpuConfig,
1896    };
1897    SpRecordTrace.appendSerialize(gpuPluginConfig);
1898    return gpuPluginConfig;
1899  }
1900
1901  freshConfigMenuDisable(disable: boolean): void {
1902    let querySelectors = this.shadowRoot?.querySelectorAll<LitMainMenuItem>('lit-main-menu-item');
1903    querySelectors!.forEach((item) => {
1904      if (disable) {
1905        item.style.pointerEvents = 'none';
1906      } else {
1907        item.style.pointerEvents = 'auto';
1908      }
1909      item.disabled = disable;
1910    });
1911  }
1912
1913  public startRefreshDeviceList(): void {
1914    if (this.refreshDeviceTimer === undefined) {
1915      this.refreshDeviceTimer = window.setInterval(() => {
1916        this.refreshDeviceList();
1917      }, 5000);
1918    }
1919  }
1920
1921  buttonDisable(disable: boolean): void {
1922    if (disable) {
1923      this.disconnectButton!.style.pointerEvents = 'none';
1924      this.recordButtonText!.textContent = this.stop;
1925      this.addButton!.style.pointerEvents = 'none';
1926      this.deviceSelect!.style.pointerEvents = 'none';
1927      this.deviceVersion!.style.pointerEvents = 'none';
1928    } else {
1929      this.recordButtonText!.textContent = this.record;
1930      this.disconnectButton!.style.pointerEvents = 'auto';
1931      this.addButton!.style.pointerEvents = 'auto';
1932      this.deviceSelect!.style.pointerEvents = 'auto';
1933      this.deviceVersion!.style.pointerEvents = 'auto';
1934    }
1935  }
1936
1937  freshMenuItemsStatus(currentValue: string): void {
1938    let litMainMenuGroup = this.shadowRoot?.querySelector<LitMainMenuGroup>('lit-main-menu-group');
1939    let litMainMenuItemNodeListOf = litMainMenuGroup!.querySelectorAll<LitMainMenuItem>('lit-main-menu-item');
1940    litMainMenuItemNodeListOf.forEach((item) => {
1941      item.back = item.title == currentValue;
1942    });
1943  }
1944
1945  synchronizeDeviceList(): void {
1946    this.deviceSelect!.innerHTML = '';
1947    if (SpRecordTrace.serialNumber != '') {
1948      let option = document.createElement('option');
1949      option.className = 'select';
1950      option.selected = true;
1951      option.value = SpRecordTrace.serialNumber;
1952      option.textContent = SpRecordTrace.serialNumber;
1953      this.deviceSelect!.appendChild(option);
1954      this.recordButton!.hidden = false;
1955      this.disconnectButton!.hidden = false;
1956      if (SpRecordTrace.selectVersion && SpRecordTrace.selectVersion != '') {
1957        this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
1958      }
1959    }
1960  }
1961}
1962