• 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 { SpJsHeap } from './setting/SpJsHeap.js';
68import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.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() {
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 spJsHeap: SpJsHeap | 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() {
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                this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
488                  PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
489                  this.recordSetting!.output,
490                  this.recordSetting!.maxDur
491                );
492              }
493            });
494          }
495        }
496      });
497    }
498  }
499
500  freshMenuDisable(disable: boolean) {
501    let mainMenu = this.sp!.shadowRoot?.querySelector('#main-menu') as LitMainMenu;
502    mainMenu.menus?.forEach((men) => {
503      men.children.forEach((child) => {
504        // @ts-ignore
505        child.disabled = disable;
506      });
507    });
508    mainMenu.menus = mainMenu.menus;
509  }
510
511  set showHint(bool: boolean) {
512    if (bool) {
513      if (this.hasAttribute('show_hint')) {
514        this.removeAttribute('show_hint');
515        setTimeout(() => {
516          this.setAttribute('show_hint', '');
517        }, 200);
518      } else {
519        this.setAttribute('show_hint', '');
520      }
521    } else {
522      this.removeAttribute('show_hint');
523    }
524  }
525
526  private refreshDeviceTimer: number | undefined;
527
528  initElements(): void {
529    let parentElement = this.parentNode as HTMLElement;
530    parentElement.style.overflow = 'hidden';
531    this.recordSetting = new SpRecordSetting();
532    this.probesConfig = new SpProbesConfig();
533    this.traceCommand = new SpTraceCommand();
534    this.spAllocations = new SpAllocations();
535    this.spRecordPerf = new SpRecordPerf();
536    this.spFileSystem = new SpFileSystem();
537    this.spSdkConfig = new SpSdkConfig();
538    this.spVmTracker = new SpVmTracker();
539    this.spHisysEvent = new SpHisysEvent();
540    this.spJsHeap = new SpJsHeap();
541    this.spRecordTemplate = new SpRecordTemplate(this);
542    this.addButton = this.shadowRoot?.querySelector<LitButton>('.add');
543    this.addButton!.addEventListener('click', () => {
544      if (this.vs) {
545        this.refreshDeviceList();
546      } else {
547        // @ts-ignore
548        HdcDeviceManager.findDevice().then((usbDevices) => {
549          log(usbDevices);
550          this.refreshDeviceList();
551        });
552      }
553    });
554    this.deviceSelect = this.shadowRoot?.querySelector('#device-select') as HTMLSelectElement;
555    this.deviceVersion = this.shadowRoot?.querySelector('#device-version') as HTMLSelectElement;
556    this.deviceSelect!.onchange = () => {
557      if (this.deviceSelect!.options.length > 0) {
558        this.recordButton!.hidden = false;
559        this.disconnectButton!.hidden = false;
560      } else {
561        this.recordButton!.hidden = true;
562        this.disconnectButton!.hidden = true;
563      }
564      let deviceItem = this.deviceSelect!.options[this.deviceSelect!.selectedIndex];
565      let value = deviceItem.value;
566      SpRecordTrace.serialNumber = value;
567      if (this.vs) {
568        let cmd = Cmd.formatString(CmdConstant.CMD_GET_VERSION_DEVICES, [SpRecordTrace.serialNumber]);
569        Cmd.execHdcCmd(cmd, (deviceVersion: string) => {
570          this.selectedDevice(deviceVersion);
571          this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
572            PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
573            this.recordSetting!.output,
574            this.recordSetting!.maxDur
575          );
576        });
577      } else {
578        HdcDeviceManager.connect(value).then((result) => {
579          if (result) {
580            HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_VERSION, true).then((deviceVersion) => {
581              this.selectedDevice(deviceVersion);
582              this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
583                PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
584                this.recordSetting!.output,
585                this.recordSetting!.maxDur
586              );
587            });
588          } else {
589            SpRecordTrace.selectVersion = SpRecordTrace.supportVersions[0];
590            this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
591            this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
592              PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
593              this.recordSetting!.output,
594              this.recordSetting!.maxDur
595            );
596          }
597        });
598      }
599    };
600    this.deviceVersion.onchange = () => {
601      let versionItem = this.deviceVersion!.options[this.deviceVersion!.selectedIndex];
602      SpRecordTrace.selectVersion = versionItem.getAttribute('device-version');
603      this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
604        PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
605        this.recordSetting!.output,
606        this.recordSetting!.maxDur
607      );
608    };
609    this.appendDeviceVersion();
610    // @ts-ignore
611    if (navigator.usb) {
612      // @ts-ignore
613      navigator.usb.addEventListener(
614        'connect',
615        // @ts-ignore
616        (ev: USBConnectionEvent) => {
617          this.usbConnectionListener(ev);
618        }
619      );
620      // @ts-ignore
621      navigator.usb.addEventListener(
622        'disconnect',
623        // @ts-ignore
624        (ev: USBConnectionEvent) => {
625          this.usbDisConnectionListener(ev);
626        }
627      );
628    }
629    this.disconnectButton = this.shadowRoot?.querySelector<LitButton>('.disconnect');
630    this.disconnectButton?.addEventListener('click', (evt) => {
631      let index = this.deviceSelect!.selectedIndex;
632      if (index != -1) {
633        let selectOption = this.deviceSelect!.options[index];
634        let value = selectOption.value;
635        HdcDeviceManager.disConnect(value).then((re) => {
636          this.deviceSelect!.removeChild(selectOption);
637          if (this.deviceSelect!.selectedIndex != -1) {
638            let item = this.deviceSelect!.options[this.deviceSelect!.selectedIndex];
639            SpRecordTrace.serialNumber = item.value;
640          } else {
641            this.recordButton!.hidden = true;
642            this.disconnectButton!.hidden = true;
643            this.sp!.search = false;
644            SpRecordTrace.serialNumber = '';
645          }
646        });
647      }
648    });
649
650    this.recordButton = this.shadowRoot?.querySelector('.record') as LitButton;
651    this.recordButtonText = this.shadowRoot?.querySelector('.record_text') as HTMLSpanElement;
652    this.sp = document.querySelector('sp-application') as SpApplication;
653    this.progressEL = this.sp.shadowRoot?.querySelector('.progress') as LitProgressBar;
654    this.litSearch = this.sp.shadowRoot?.querySelector('#lit-record-search') as LitSearch;
655    if (this.deviceSelect!.options && this.deviceSelect!.options.length > 0) {
656      this.disconnectButton!.hidden = false;
657      this.recordButton!.hidden = false;
658    } else {
659      this.disconnectButton!.hidden = true;
660      this.recordButton!.hidden = true;
661    }
662    this.recordButton!.addEventListener('click', () => {
663      if (this.recordButtonText!.textContent == this.record) {
664        this.recordButtonListener();
665      } else {
666        this.stopRecordListener();
667      }
668    });
669    this.spRecordPerf!.addEventListener('addProbe', () => {
670      this.showHint = false;
671    });
672    this.spAllocations!.addEventListener('addProbe', () => {
673      this.showHint = false;
674    });
675    this.probesConfig!.addEventListener('addProbe', () => {
676      this.showHint = false;
677    });
678    this.spRecordTemplate!.addEventListener('addProbe', () => {
679      this.showHint = false;
680    });
681    this.menuGroup = this.shadowRoot?.querySelector('#menu-group') as LitMainMenuGroup;
682    this.appContent = this.shadowRoot?.querySelector('#app-content') as HTMLElement;
683    if (this.record_template) {
684      this.appContent.append(this.spRecordTemplate);
685    } else {
686      this.appContent.append(this.recordSetting);
687    }
688    this.initMenuItems();
689  }
690
691  private selectedDevice(deviceVersion: string) {
692    let deviceVersionItem = SpRecordTrace.supportVersions.filter((item) => deviceVersion.indexOf(item) != -1);
693    if (deviceVersionItem.length > 0) {
694      SpRecordTrace.selectVersion = deviceVersionItem[0];
695    } else {
696      SpRecordTrace.selectVersion = SpRecordTrace.supportVersions[0];
697    }
698    this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
699  }
700
701  private appendDeviceVersion() {
702    SpRecordTrace.supportVersions.forEach((supportVersion) => {
703      let option = document.createElement('option');
704      option.className = 'select';
705      option.textContent = `OpenHarmony-${supportVersion}`;
706      option.setAttribute('device-version', supportVersion);
707      this.deviceVersion!.append(option);
708    });
709  }
710
711  private setDeviceVersionSelect(selected: string) {
712    let children = this.deviceVersion!.children;
713    for (let i = 0; i < children.length; i++) {
714      let child = children[i] as HTMLOptionElement;
715      if (child.getAttribute('device-version') === selected) {
716        child.selected = true;
717        break;
718      }
719    }
720  }
721
722  stopRecordListener() {
723    this.recordButtonText!.textContent = 'Record';
724    if (this.vs) {
725      let cmd = Cmd.formatString(CmdConstant.CMS_HDC_STOP, [SpRecordTrace.serialNumber]);
726      Cmd.execHdcCmd(cmd, (res: string) => {
727        this.freshMenuDisable(false);
728        this.freshConfigMenuDisable(false);
729        this.progressEL!.loading = false;
730        this.sp!.search = false;
731        this.litSearch!.clear();
732        this.addButton!.style.pointerEvents = 'auto';
733        this.deviceSelect!.style.pointerEvents = 'auto';
734        this.disconnectButton!.style.pointerEvents = 'auto';
735        this.deviceVersion!.style.pointerEvents = 'auto';
736      });
737    } else {
738      let selectedOption = this.deviceSelect!.options[this.deviceSelect!.selectedIndex] as HTMLOptionElement;
739      HdcDeviceManager.connect(selectedOption.value).then((result) => {
740        if (result) {
741          this.freshMenuDisable(false);
742          this.freshConfigMenuDisable(false);
743          try {
744            this.progressEL!.loading = false;
745            this.sp!.search = false;
746            this.litSearch!.clear();
747            this.disconnectButton!.style.pointerEvents = 'auto';
748            this.addButton!.style.pointerEvents = 'auto';
749            this.deviceSelect!.style.pointerEvents = 'auto';
750            this.deviceVersion!.style.pointerEvents = 'auto';
751            SpRecordTrace.stopRecord = true;
752            HdcDeviceManager.stopHiprofiler(CmdConstant.CMS_STOP, true).then((result) => {});
753          } catch (exception) {
754            log(exception);
755          }
756        }
757      });
758    }
759  }
760
761  private initMenuItems() {
762    let that = this;
763    if (this.record_template) {
764      this._menuItems = [
765        {
766          title: 'Record setting',
767          icon: 'properties',
768          fileChoose: false,
769          clickHandler: function (ev: InputEvent) {
770            that.appContent!.innerHTML = '';
771            that.appContent!.append(that.recordSetting!);
772            that.freshMenuItemsStatus('Record setting');
773          },
774        },
775        {
776          title: 'Trace template',
777          icon: 'realIntentionBulb',
778          clickHandler: function (ev: InputEvent) {
779            that.appContent!.innerHTML = '';
780            that.appContent!.append(that.spRecordTemplate!);
781            that.freshMenuItemsStatus('Trace template');
782          },
783        },
784        {
785          title: 'Trace command',
786          icon: 'dbsetbreakpoint',
787          fileChoose: false,
788          clickHandler: function (ev: InputEvent) {
789            that.appContent!.innerHTML = '';
790            that.appContent!.append(that.traceCommand!);
791            that.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
792              PluginConvertUtils.BeanToCmdTxt(that.makeRequest(), false),
793              that.recordSetting!.output,
794              that.recordSetting!.maxDur
795            );
796            that.freshMenuItemsStatus('Trace command');
797          },
798        },
799      ];
800    } else {
801      this._menuItems = [
802        {
803          title: 'Record setting',
804          icon: 'properties',
805          fileChoose: false,
806          clickHandler: function (ev: InputEvent) {
807            that.appContent!.innerHTML = '';
808            that.appContent!.append(that.recordSetting!);
809            that.freshMenuItemsStatus('Record setting');
810          },
811        },
812        {
813          title: 'Trace command',
814          icon: 'dbsetbreakpoint',
815          fileChoose: false,
816          clickHandler: function (ev: InputEvent) {
817            that.freshMenuItemsStatus('Trace command');
818            let request = that.makeRequest();
819            that.appContent!.innerHTML = '';
820            that.appContent!.append(that.traceCommand!);
821            that.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
822              PluginConvertUtils.BeanToCmdTxt(request, false),
823              that.recordSetting!.output,
824              that.recordSetting!.maxDur
825            );
826          },
827        },
828        {
829          title: 'Probes config',
830          icon: 'realIntentionBulb',
831          fileChoose: false,
832          clickHandler: function (ev: InputEvent) {
833            that.appContent!.innerHTML = '';
834            that.appContent!.append(that.probesConfig!);
835            that.freshMenuItemsStatus('Probes config');
836          },
837        },
838        {
839          title: 'Native Memory',
840          icon: 'externaltools',
841          fileChoose: false,
842          clickHandler: function (ev: InputEvent) {
843            that.appContent!.innerHTML = '';
844            that.appContent!.append(that.spAllocations!);
845            that.freshMenuItemsStatus('Native Memory');
846          },
847        },
848        {
849          title: 'Hiperf',
850          icon: 'realIntentionBulb',
851          fileChoose: false,
852          clickHandler: function (ev: InputEvent) {
853            that.appContent!.innerHTML = '';
854            that.appContent!.append(that.spRecordPerf!);
855            that.freshMenuItemsStatus('Hiperf');
856          },
857        },
858        {
859          title: 'eBPF Config',
860          icon: 'file-config',
861          fileChoose: false,
862          clickHandler: function (ev: InputEvent) {
863            that.appContent!.innerHTML = '';
864            that.appContent!.append(that.spFileSystem!);
865            that.freshMenuItemsStatus('eBPF Config');
866          },
867        },
868        {
869          title: 'VM Tracker',
870          icon: 'vm-tracker',
871          fileChoose: false,
872          clickHandler: function (ev: InputEvent) {
873            that.appContent!.innerHTML = '';
874            that.appContent!.append(that.spVmTracker!);
875            that.freshMenuItemsStatus('VM Tracker');
876          },
877        },
878        {
879          title: 'HiSystemEvent',
880          icon: 'externaltools',
881          fileChoose: false,
882          clickHandler: function (ev: InputEvent) {
883            that.appContent!.innerHTML = '';
884            that.appContent!.append(that.spHisysEvent!);
885            that.freshMenuItemsStatus('HiSystemEvent');
886          },
887        },
888        {
889          title: 'JS Heap',
890          icon: 'file-config',
891          fileChoose: false,
892          clickHandler: function (ev: InputEvent) {
893            that.appContent!.innerHTML = '';
894            that.appContent!.append(that.spJsHeap!);
895            that.freshMenuItemsStatus('JS Heap');
896          },
897        },
898        {
899          title: 'SDK Config',
900          icon: 'file-config',
901          fileChoose: false,
902          clickHandler: function (ev: InputEvent) {
903            that.appContent!.innerHTML = '';
904            that.appContent!.append(that.spSdkConfig!);
905            that.freshMenuItemsStatus('SDK Config');
906          },
907        },
908      ];
909    }
910
911    this._menuItems?.forEach((item) => {
912      let th = new LitMainMenuItem();
913      th.setAttribute('icon', item.icon || '');
914      th.setAttribute('title', item.title || '');
915      th.style.height = '60px';
916      th.style.fontFamily = 'Helvetica-Bold';
917      th.style.fontSize = '16px';
918      th.style.lineHeight = '28px';
919      th.style.fontWeight = '700';
920      th.removeAttribute('file');
921      th.addEventListener('click', (e) => {
922        if (item.clickHandler) {
923          item.clickHandler(item);
924        }
925      });
926      this.menuGroup!.appendChild(th);
927    });
928  }
929  // @ts-ignore
930  usbConnectionListener(event: USBConnectionEvent) {
931    if (event.isTrusted) {
932      this.recordButton!.hidden = false;
933      this.disconnectButton!.hidden = false;
934      // @ts-ignore
935      let usbDevice: USBDevice = event.device;
936      let option = document.createElement('option');
937      option.className = 'select';
938      if (typeof usbDevice.serialNumber === 'string') {
939        option.value = usbDevice.serialNumber;
940      }
941      option.selected = true;
942      option.textContent = usbDevice!.serialNumber ? usbDevice!.serialNumber.replace(/"/g, '') : 'hdc Device';
943      this.deviceSelect!.appendChild(option);
944      SpRecordTrace.serialNumber = option.value;
945    }
946  }
947
948  // @ts-ignore
949  usbDisConnectionListener(event: USBConnectionEvent) {
950    // @ts-ignore
951    let disConnectDevice: USBDevice = event.device;
952    for (let index = 0; index < this.deviceSelect!.children.length; index++) {
953      let option = this.deviceSelect!.children[index] as HTMLOptionElement;
954      if (option.value == disConnectDevice.serialNumber) {
955        let optValue = option.value;
956        HdcDeviceManager.disConnect(optValue).then(() => {});
957        this.deviceSelect!.removeChild(option);
958        if (SpRecordTrace.serialNumber == optValue) {
959          let options = this.deviceSelect!.options;
960          if (options.length > 0) {
961            let selectedOpt = options[this.deviceSelect!.selectedIndex];
962            SpRecordTrace.serialNumber = selectedOpt.value;
963          } else {
964            this.recordButton!.hidden = true;
965            this.disconnectButton!.hidden = true;
966            SpRecordTrace.serialNumber = '';
967          }
968        }
969      }
970    }
971  }
972
973  recordButtonListener() {
974    SpRecordTrace.stopRecord = false;
975    let request = this.makeRequest();
976    if (request.pluginConfigs.length == 0) {
977      this.showHint = true;
978      return;
979    } else {
980      this.showHint = false;
981    }
982    let traceCommandStr = PluginConvertUtils.createHdcCmd(
983      PluginConvertUtils.BeanToCmdTxt(request, false),
984      this.recordSetting!.output,
985      this.recordSetting!.maxDur
986    );
987    let pluginList: Array<string> = [];
988    request.pluginConfigs.forEach((pluginConfig) => {
989      pluginList.push(pluginConfig.pluginName);
990    });
991    SpStatisticsHttpUtil.addOrdinaryVisitAction({
992      action: 'config_page',
993      event: 'online_record',
994      eventData: {
995        plugin: pluginList,
996      },
997    });
998    let selectedOption = this.deviceSelect!.options[this.deviceSelect!.selectedIndex] as HTMLOptionElement;
999    if (selectedOption) {
1000      SpRecordTrace.serialNumber = selectedOption.value;
1001    } else {
1002      this.sp!.search = true;
1003      this.litSearch!.clear();
1004      this.progressEL!.loading = false;
1005      this.litSearch!.setPercent('please connect device', -2);
1006    }
1007
1008    if (this.vs) {
1009      this.appContent!.innerHTML = '';
1010      this.appContent!.append(this.traceCommand!);
1011      this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
1012        PluginConvertUtils.BeanToCmdTxt(this.makeRequest(), false),
1013        this.recordSetting!.output,
1014        this.recordSetting!.maxDur
1015      );
1016      this.freshMenuItemsStatus('Trace command');
1017      Cmd.execHdcCmd(Cmd.formatString(CmdConstant.CMS_HDC_STOP, [SpRecordTrace.serialNumber]), (stopRes: string) => {
1018        let cmd = Cmd.formatString(CmdConstant.CMD_MOUNT_DEVICES, [SpRecordTrace.serialNumber]);
1019        Cmd.execHdcCmd(cmd, (res: string) => {
1020          this.sp!.search = true;
1021          this.progressEL!.loading = true;
1022          this.litSearch!.clear();
1023          this.litSearch!.setPercent('tracing  ' + this.recordSetting!.maxDur * 1000 + 'ms', -1);
1024          this.initRecordUIState();
1025          this.recordButtonText!.textContent = this.stop;
1026          Cmd.execHdcTraceCmd(traceCommandStr, SpRecordTrace.serialNumber, (traceResult: string) => {
1027            if (traceResult.indexOf('DestroySession done') != -1) {
1028              this.litSearch!.setPercent('tracing htrace down', -1);
1029              let cmd = Cmd.formatString(CmdConstant.CMD_FIEL_RECV_DEVICES, [
1030                SpRecordTrace.serialNumber,
1031                this.recordSetting!.output,
1032              ]);
1033              Cmd.execFileRecv(cmd, this.recordSetting!.output, (rt: ArrayBuffer) => {
1034                this.litSearch!.setPercent('downloading Hitrace file ', 101);
1035                let fileName = this.recordSetting!.output.substring(this.recordSetting!.output.lastIndexOf('/') + 1);
1036                let file = new File([rt], fileName);
1037                let main = this!.parentNode!.parentNode!.querySelector('lit-main-menu') as LitMainMenu;
1038                let children = main.menus as Array<MenuGroup>;
1039                let child = children[0].children as Array<MenuItem>;
1040                let fileHandler = child[0].fileHandler;
1041                if (fileHandler && !SpRecordTrace.stopRecord) {
1042                  this.recordButtonText!.textContent = this.record;
1043                  this.freshMenuDisable(false);
1044                  this.freshConfigMenuDisable(false);
1045                  fileHandler({ detail: file });
1046                } else {
1047                  SpRecordTrace.stopRecord = false;
1048                }
1049              });
1050            } else {
1051              this.litSearch!.setPercent('tracing htrace failed, please check your config ', -2);
1052              this.recordButtonText!.textContent = this.record;
1053              this.freshMenuDisable(false);
1054              this.freshConfigMenuDisable(false);
1055              this.progressEL!.loading = false;
1056            }
1057            this.buttonDisable(false);
1058          });
1059        });
1060      });
1061    } else {
1062      HdcDeviceManager.connect(selectedOption.value).then((result) => {
1063        log('result is ' + result);
1064        if (result) {
1065          this.appContent!.innerHTML = '';
1066          this.appContent!.append(this.traceCommand!);
1067          let config = this.makeRequest();
1068          this.traceCommand!.hdcCommon = PluginConvertUtils.createHdcCmd(
1069            PluginConvertUtils.BeanToCmdTxt(config, false),
1070            this.recordSetting!.output,
1071            this.recordSetting!.maxDur
1072          );
1073          this.freshMenuItemsStatus('Trace command');
1074          try {
1075            HdcDeviceManager.stopHiprofiler(CmdConstant.CMS_STOP, true).then(() => {
1076              HdcDeviceManager.shellResultAsString(CmdConstant.CMD_MOUNT, true).then(() => {
1077                this.sp!.search = true;
1078                this.progressEL!.loading = true;
1079                this.litSearch!.clear();
1080                this.litSearch!.setPercent('tracing  ' + this.recordSetting!.maxDur * 1000 + 'ms', -1);
1081                this.buttonDisable(true);
1082                this.freshMenuDisable(true);
1083                this.freshConfigMenuDisable(true);
1084                HdcDeviceManager.shellResultAsString(CmdConstant.CMD_SHELL + traceCommandStr, false).then(
1085                  (traceResult) => {
1086                    let re = this.isSuccess(traceResult);
1087                    if (re == 0) {
1088                      this.litSearch!.setPercent('tracing htrace down', -1);
1089                      HdcDeviceManager.shellResultAsString(
1090                        CmdConstant.CMD_TRACE_FILE_SIZE + this.recordSetting!.output,
1091                        false
1092                      ).then((traceFileSize) => {
1093                        if (traceFileSize.indexOf('No such') != -1) {
1094                          this.litSearch!.setPercent('No such file or directory', -2);
1095                          this.buttonDisable(false);
1096                          this.freshConfigMenuDisable(false);
1097                          this.freshMenuDisable(false);
1098                        } else if (Number(traceFileSize) <= SpRecordTrace.MaxFileSize) {
1099                          HdcDeviceManager.fileRecv(this.recordSetting!.output, (perNumber: number) => {
1100                            this.litSearch!.setPercent('downloading Hitrace file ', perNumber);
1101                          }).then((pullRes) => {
1102                            this.litSearch!.setPercent('downloading Hitrace file ', 101);
1103                            pullRes.arrayBuffer().then((buffer) => {
1104                              let fileName = this.recordSetting!.output.substring(
1105                                this.recordSetting!.output.lastIndexOf('/') + 1
1106                              );
1107                              let file = new File([buffer], fileName);
1108                              let main = this!.parentNode!.parentNode!.querySelector('lit-main-menu') as LitMainMenu;
1109                              let children = main.menus as Array<MenuGroup>;
1110                              let child = children[0].children as Array<MenuItem>;
1111                              let fileHandler = child[0].fileHandler;
1112                              if (fileHandler && !SpRecordTrace.stopRecord) {
1113                                this.freshConfigMenuDisable(false);
1114                                this.freshMenuDisable(false);
1115                                this.buttonDisable(false);
1116                                fileHandler({
1117                                  detail: file,
1118                                });
1119                              } else {
1120                                SpRecordTrace.stopRecord = false;
1121                              }
1122                            });
1123                          });
1124                        } else {
1125                          this.recordButtonText!.textContent = this.record;
1126                          this.litSearch!.setPercent('htrace file is too big', -2);
1127                          this.buttonDisable(false);
1128                          this.freshConfigMenuDisable(false);
1129                          this.freshMenuDisable(false);
1130                        }
1131                      });
1132                    } else if (re == 2) {
1133                      this.litSearch!.setPercent('stop tracing htrace ', -1);
1134                      this.freshConfigMenuDisable(false);
1135                      this.freshMenuDisable(false);
1136                      this.buttonDisable(false);
1137                    } else if (re == -1) {
1138                      this.litSearch!.setPercent('The device is abnormal', -2);
1139                      this.progressEL!.loading = false;
1140                      this.freshConfigMenuDisable(false);
1141                      this.freshMenuDisable(false);
1142                      this.buttonDisable(false);
1143                    } else {
1144                      this.litSearch!.setPercent('tracing htrace failed, please check your config ', -2);
1145                      this.freshConfigMenuDisable(false);
1146                      this.freshMenuDisable(false);
1147                      this.buttonDisable(false);
1148                    }
1149                  }
1150                );
1151              });
1152            });
1153          } catch (e) {
1154            this.freshMenuDisable(false);
1155            this.freshConfigMenuDisable(false);
1156            this.buttonDisable(false);
1157          }
1158        } else {
1159          this.sp!.search = true;
1160          this.litSearch!.clear();
1161          this.litSearch!.setPercent('please kill other hdc-server !', -2);
1162        }
1163      });
1164    }
1165  }
1166
1167  private initRecordUIState() {
1168    this.buttonDisable(true);
1169    this.freshMenuDisable(true);
1170    this.freshConfigMenuDisable(true);
1171  }
1172
1173  private isSuccess(traceResult: string): number {
1174    if (traceResult.indexOf('CreateSession FAIL') != -1 || traceResult.indexOf('failed') != -1) {
1175      return 1;
1176    } else if (traceResult.indexOf('Signal') != -1) {
1177      return 2;
1178    } else if (traceResult.indexOf('The device is abnormal') != -1) {
1179      return -1;
1180    } else {
1181      return 0;
1182    }
1183  }
1184
1185  private makeRequest = () => {
1186    let request = this.createSessionRequest();
1187    if (this.record_template) {
1188      let templateConfigs = this.spRecordTemplate?.getTemplateConfig();
1189      templateConfigs?.forEach((config) => {
1190        request.pluginConfigs.push(config);
1191      });
1192    } else {
1193      let hasMonitorMemory = false;
1194      let hasSamps = false;
1195      if (this.probesConfig!.traceConfig.length > 0) {
1196        if (
1197          this.probesConfig!.traceConfig.find((value) => {
1198            return value != 'FPS';
1199          })
1200        ) {
1201          request.pluginConfigs.push(this.createHtracePluginConfig());
1202        }
1203        if (this.probesConfig!.traceConfig.indexOf('FPS') != -1) {
1204          request.pluginConfigs.push(this.createFpsPluginConfig());
1205        }
1206      }
1207      if (this.probesConfig!.recordAbility) {
1208        hasMonitorMemory = true;
1209        this.createMonitorPlugin(this, request);
1210      }
1211      let reportingFrequency: number;
1212      if (this.recordSetting!.maxDur > 20) {
1213        reportingFrequency = 5;
1214      } else {
1215        reportingFrequency = 2;
1216      }
1217      if (this.spVmTracker!.startSamp && this.spVmTracker!.process != '') {
1218        hasSamps = true;
1219      }
1220      if (this.probesConfig!.memoryConfig.length > 0 || hasMonitorMemory || hasSamps) {
1221        request.pluginConfigs.push(
1222          this.createMemoryPluginConfig(
1223            reportingFrequency,
1224            this.probesConfig!.memoryConfig.length > 0,
1225            hasMonitorMemory,
1226            hasSamps
1227          )
1228        );
1229      }
1230      if (this.spAllocations!.appProcess != '') {
1231        request.pluginConfigs.push(this.createNativePluginConfig(reportingFrequency));
1232      }
1233      if (this.spRecordPerf!.startSamp) {
1234        request.pluginConfigs.push(this.createHiperConfig(reportingFrequency));
1235      }
1236      if (this.spFileSystem!.startRecord) {
1237        request.pluginConfigs.push(this.createSystemConfig());
1238      }
1239      if (this.spSdkConfig!.startSamp && this.spSdkConfig!.getPlugName() != '') {
1240        request.pluginConfigs.push(this.createSdkConfig());
1241      }
1242      if (this.spHisysEvent?.startSamp) {
1243        request.pluginConfigs.push(this.createHiSystemEventPluginConfig(this.spHisysEvent.process));
1244      }
1245      if (this.spJsHeap!.process != '') {
1246        request.pluginConfigs.push(this.createJsHeapConfig());
1247      }
1248    }
1249    return request;
1250  };
1251
1252  private createSessionRequest() {
1253    let bufferConfig: ProfilerSessionConfigBufferConfig = {
1254      pages: this.recordSetting!.bufferSize * 256,
1255      policy: ProfilerSessionConfigBufferConfigPolicy.RECYCLE,
1256    };
1257    let sessionConfig: ProfilerSessionConfig = {
1258      buffers: [bufferConfig],
1259      sessionMode: ProfilerSessionConfigMode.OFFLINE,
1260      resultFile: this.recordSetting!.output,
1261      resultMaxSize: 0,
1262      sampleDuration: this.recordSetting!.maxDur * 1000,
1263      keepAliveTime: 0,
1264    };
1265    let request: CreateSessionRequest = {
1266      requestId: 1,
1267      sessionConfig: sessionConfig,
1268      pluginConfigs: [],
1269    };
1270    return request;
1271  }
1272
1273  private createMonitorPlugin(that: this, request: CreateSessionRequest) {
1274    let processPlugin = that.createProcessPlugin();
1275    let cpuPlugin = that.createCpuPlugin();
1276    let diskIoPlugin = that.createDiskIOPlugin();
1277    let netWorkPlugin = that.createNetworkPlugin();
1278    request.pluginConfigs.push(processPlugin);
1279    request.pluginConfigs.push(cpuPlugin);
1280    request.pluginConfigs.push(diskIoPlugin);
1281    request.pluginConfigs.push(netWorkPlugin);
1282  }
1283
1284  private createNetworkPlugin() {
1285    let netWorkConfig: NetworkConfig = {};
1286    let netWorkPlugin: ProfilerPluginConfig<NetworkConfig> = {
1287      pluginName: 'network-plugin',
1288      sampleInterval: 1000,
1289      configData: netWorkConfig,
1290    };
1291    SpRecordTrace.appendSerialize(netWorkPlugin);
1292    return netWorkPlugin;
1293  }
1294
1295  private createDiskIOPlugin() {
1296    let diskIoConfig: DiskioConfig = {
1297      reportIoStats: 'IO_REPORT',
1298    };
1299    let diskIoPlugin: ProfilerPluginConfig<DiskioConfig> = {
1300      pluginName: 'diskio-plugin',
1301      sampleInterval: 1000,
1302      configData: diskIoConfig,
1303    };
1304    SpRecordTrace.appendSerialize(diskIoPlugin);
1305    return diskIoPlugin;
1306  }
1307
1308  private createCpuPlugin() {
1309    let cpuConfig: CpuConfig = {
1310      pid: 0,
1311      reportProcessInfo: true,
1312    };
1313    let cpuPlugin: ProfilerPluginConfig<CpuConfig> = {
1314      pluginName: 'cpu-plugin',
1315      sampleInterval: 1000,
1316      configData: cpuConfig,
1317    };
1318    SpRecordTrace.appendSerialize(cpuPlugin);
1319    return cpuPlugin;
1320  }
1321
1322  private createProcessPlugin() {
1323    let processConfig: ProcessConfig = {
1324      report_process_tree: true,
1325      report_cpu: true,
1326      report_diskio: true,
1327      report_pss: true,
1328    };
1329    let processPlugin: ProfilerPluginConfig<ProcessConfig> = {
1330      pluginName: 'process-plugin',
1331      sampleInterval: 1000,
1332      configData: processConfig,
1333    };
1334    SpRecordTrace.appendSerialize(processPlugin);
1335    return processPlugin;
1336  }
1337
1338  createTraceEvents(traceConfig: Array<string>): Array<string> {
1339    let traceEvents = new Set<string>();
1340    traceConfig.forEach((config) => {
1341      switch (config) {
1342        case 'Scheduling details':
1343          this.schedulingEvents.forEach((eve: string) => {
1344            traceEvents.add(eve);
1345          });
1346          break;
1347        case 'CPU Frequency and idle states':
1348          this.cpuFreqEvents.forEach((eve: string) => {
1349            traceEvents.add(eve);
1350          });
1351          break;
1352        case 'High frequency memory':
1353          this.highFrequencyEvents.forEach((eve: string) => {
1354            traceEvents.add(eve);
1355          });
1356          break;
1357        case 'Advanced ftrace config':
1358          this.advancedConfigEvents.forEach((eve: string) => {
1359            traceEvents.add(eve);
1360          });
1361          break;
1362        case 'Syscalls':
1363          this.sysCallsEvents.forEach((eve: string) => {
1364            traceEvents.add(eve);
1365          });
1366          break;
1367        case 'Board voltages & frequency':
1368          this.powerEvents.forEach((eve: string) => {
1369            traceEvents.add(eve);
1370          });
1371          break;
1372      }
1373    });
1374    let ftraceEventsArray: string[] = [];
1375    info('traceEvents length is: ', traceEvents.size);
1376    for (const ftraceEvent of traceEvents) {
1377      ftraceEventsArray.push(ftraceEvent);
1378    }
1379    return ftraceEventsArray;
1380  }
1381
1382  initHtml(): string {
1383    return `
1384        <style>
1385        :host{
1386            display: block;
1387            height: 100%;
1388            width: 100%;
1389            background-color: var(--dark-background5,#F6F6F6);
1390        }
1391        .container {
1392            background-color: var(--dark-background5,#F6F6F6);
1393            height:100%;
1394        }
1395
1396        .header {
1397            padding-top: 30px;
1398            padding-bottom: 20px;
1399            background-color: var(--dark-background3,#FFFFFF);
1400            width: 100%;
1401        }
1402
1403        .span-col-2{
1404             margin-left: 20px;
1405             display: flex;
1406             align-items: center
1407        }
1408
1409        .header-right {
1410           display: flex;
1411           margin-left: auto;
1412           margin-right: 5%;
1413        }
1414        .header-des{
1415          font-family: PingFangSC-Regular;
1416          font-size: 1em;
1417          color:  #999999;
1418          text-align: left;
1419          font-weight: 400;
1420        }
1421
1422        .target {
1423           opacity: 0.9;
1424           font-family: Helvetica;
1425           font-size: 14px;
1426           color: var(--dark-color2,#000000);
1427           line-height: 16px;
1428           font-weight: 400;
1429           white-space:nowrap;
1430           align-self: center;
1431        }
1432
1433        .select{
1434           width: 300px;
1435           height: 32px;
1436           margin-left: 14px;
1437           margin-right: 10px;
1438           background: var(--dark-background1,#ffffff);
1439           border: 1px solid var(--dark-color1,#4D4D4D);
1440           border-radius: 16px;
1441           opacity: 0.6;
1442           font-family: Helvetica;
1443           font-size: 14px;
1444           color: var(--dark-color1,#000000);
1445           text-align: center;
1446           line-height: 20px;
1447           font-weight: 400;
1448           padding: 5px 10px 5px 10px;
1449           -webkit-appearance: none;
1450           background: url('img/down.png') no-repeat 96% center;
1451        }
1452        .device_version {
1453           width: 200px;
1454           height: 32px;
1455           margin-left: 5px;
1456           margin-right: 24px;
1457           background: var(--dark-background1,#ffffff);
1458           border: 1px solid var(--dark-color1,#4D4D4D);
1459           border-radius: 16px;
1460           opacity: 0.6;
1461           font-family: Helvetica;
1462           font-size: 14px;
1463           color: var(--dark-color1,#000000);
1464           text-align: center;
1465           line-height: 20px;
1466           font-weight: 400;
1467           padding: 5px 10px 5px 10px;
1468           -webkit-appearance: none;
1469           background: url('img/down.png') no-repeat 96% center;
1470        }
1471        .body{
1472            width: 90%;
1473            height:80vh;
1474            margin-left: 3%;
1475            margin-top: 2%;
1476            margin-bottom: 2%;
1477            display: grid;
1478            grid-template-columns: min-content  1fr;
1479            background-color: var(--dark-background3,#FFFFFF);
1480            border-radius: 16px 16px 16px 16px;
1481        }
1482
1483        .menugroup{
1484           height: 100%;
1485           background: var(--dark-background3,#FFFFFF);
1486        }
1487        .menuitem{
1488          background: var(--dark-background3,#FFFFFF);
1489        }
1490        .content{
1491          background: var(--dark-background3,#FFFFFF);
1492          border-style: none none none solid;
1493          border-width: 1px;
1494          border-color: rgba(166,164,164,0.2);
1495          border-radius: 0px 16px 16px 0px;
1496        }
1497        :host([show_hint]) #hint {
1498            color: #DB5860;
1499            position: absolute;
1500            left:1%;
1501            animation: textRoll 5s ease-in-out 0s backwards;
1502            white-space: nowrap;
1503            display: block;
1504            font-weight: 700;
1505        }
1506        #hint {
1507           display: none;
1508        }
1509
1510        @keyframes textRoll {
1511            0% {
1512                left: 1%;
1513
1514            }
1515            100% {
1516                left:100%;
1517            }
1518        }
1519
1520        </style>
1521        <div class="container">
1522         <div class="header">
1523           <div style="display: flex;margin-bottom: 24px;margin-left:20px;">
1524             <span class="target">Target Platform:</span>
1525               <select class="select" id = "device-select">
1526               </select>
1527               <select class="device_version" id = "device-version">
1528               </select>
1529              <lit-button style="width: 180px" class="add" height="32px" width="164px" color="#0A59F7" font_size="14px" border="1px solid #0A59F7"
1530              padding="0 0 0 12px" justify_content="left" icon="add" margin_icon="0 10px 0 8px">Add HDC Device</lit-button>
1531              <div class="header-right">
1532              <lit-button class="disconnect" style="margin-right: 30px" height="32px" width="96px" font_size="14px" justify_content="center" color="#FFFFFF"
1533              border_radius="16px" back='#0A59F7' opacity="0.6" border="0 solid">Disconnect</lit-button>
1534              <lit-button class="record" height="32px" width="96px" font_size="14px" justify_content="center" color="#FFFFFF"
1535              border_radius="16px" back='#0A59F7' opacity="0.6" border="0 solid"><span class="record_text">Record</span></lit-button>
1536              </div>
1537             </div>
1538              <div class="span-col-2" >
1539                 <span class="header-des" id="hint">It looks like you didn't add any probes. Please add at least one</span>
1540              </div>
1541         </div>
1542
1543         <div class="body">
1544            <lit-main-menu-group class="menugroup" id= "menu-group" title="" nocollapsed radius></lit-main-menu-group>
1545            <div id="app-content" class="content">
1546            </div>
1547         </div>
1548        </div>
1549        `;
1550  }
1551
1552  private createHilogConfig(probesConfig: SpProbesConfig, reportingFrequency: number) {
1553    let hilogConfig: HilogConfig = {
1554      deviceType: Type.HI3516,
1555      logLevel: levelFromJSON(probesConfig.hilogConfig[0]),
1556      needClear: true,
1557    };
1558    let hilogConfigProfilerPluginConfig: ProfilerPluginConfig<HilogConfig> = {
1559      pluginName: 'hilog-plugin',
1560      sampleInterval: reportingFrequency * 1000,
1561      configData: hilogConfig,
1562    };
1563    SpRecordTrace.appendSerialize(hilogConfigProfilerPluginConfig);
1564    return hilogConfigProfilerPluginConfig;
1565  }
1566
1567  private isNumber(str: string) {
1568    return !isNaN(Number(str));
1569  }
1570
1571  private createHiperConfig(reportingFrequency: number) {
1572    let perfConfig = this.spRecordPerf!.getPerfConfig();
1573    let recordArgs = '';
1574    recordArgs = recordArgs + '-f ' + perfConfig?.frequency;
1575    if (perfConfig?.process && !perfConfig?.process.includes('ALL') && perfConfig?.process.length > 0) {
1576      let process = perfConfig.process;
1577      if (process.indexOf(',') != -1) {
1578        let processIdOrName = process.split(',');
1579        if (this.isNumber(processIdOrName[0])) {
1580          recordArgs = recordArgs + ' -p ' + perfConfig?.process;
1581        } else {
1582          recordArgs = recordArgs + ' --app ' + perfConfig?.process;
1583        }
1584      } else {
1585        if (this.isNumber(process)) {
1586          recordArgs = recordArgs + ' -p ' + perfConfig?.process;
1587        } else {
1588          recordArgs = recordArgs + ' --app ' + perfConfig?.process;
1589        }
1590      }
1591    } else {
1592      recordArgs = recordArgs + ' -a ';
1593    }
1594    if (perfConfig?.cpu && !perfConfig?.cpu.includes('ALL') && perfConfig?.cpu.length > 0) {
1595      recordArgs = recordArgs + ' -c ' + perfConfig?.cpu;
1596    }
1597    if (perfConfig?.cpuPercent != 0) {
1598      recordArgs = recordArgs + ' --cpu-limit ' + perfConfig?.cpuPercent;
1599    }
1600    if (perfConfig?.eventList && !perfConfig?.eventList.includes('NONE') && perfConfig?.eventList.length > 0) {
1601      recordArgs = recordArgs + ' -e ' + perfConfig?.eventList;
1602      if (perfConfig?.isOffCpu) {
1603        recordArgs = recordArgs + ',sched:sched_waking';
1604      }
1605    } else {
1606      recordArgs = recordArgs + ' -e hw-cpu-cycles';
1607      if (perfConfig?.isOffCpu) {
1608        recordArgs = recordArgs + ',sched:sched_waking';
1609      }
1610    }
1611    if (perfConfig?.callStack != 'none') {
1612      recordArgs = recordArgs + ' --call-stack ' + perfConfig?.callStack;
1613    }
1614
1615    if (perfConfig?.branch != 'none') {
1616      recordArgs = recordArgs + ' -j ' + perfConfig?.branch;
1617    }
1618
1619    if (perfConfig?.clockType) {
1620      recordArgs = recordArgs + ' --clockid ' + perfConfig?.clockType;
1621    }
1622
1623    if (perfConfig?.isOffCpu) {
1624      recordArgs = recordArgs + ' --offcpu';
1625    }
1626
1627    if (perfConfig?.noInherit) {
1628      recordArgs = recordArgs + ' --no-inherit';
1629    }
1630
1631    if (perfConfig?.mmap) {
1632      recordArgs = recordArgs + ' -m ' + perfConfig.mmap;
1633    }
1634    info('record config Args is: ', recordArgs);
1635    let hiPerf: HiperfPluginConfig = {
1636      isRoot: false,
1637      outfileName: '/data/local/tmp/perf.data',
1638      recordArgs: recordArgs,
1639    };
1640    let hiPerfPluginConfig: ProfilerPluginConfig<HiperfPluginConfig> = {
1641      pluginName: 'hiperf-plugin',
1642      sampleInterval: reportingFrequency * 1000,
1643      configData: hiPerf,
1644    };
1645    return hiPerfPluginConfig;
1646  }
1647
1648  private createSystemConfig() {
1649    let systemConfig = this.spFileSystem!.getSystemConfig();
1650    let recordArgs = 'hiebpf';
1651    let recordEvent = [];
1652    if (this.spFileSystem?.startFileSystem) {
1653      recordEvent.push('fs');
1654    }
1655    if (this.spFileSystem?.startVirtualMemory) {
1656      recordEvent.push('ptrace');
1657    }
1658    if (this.spFileSystem?.startIo) {
1659      recordEvent.push('bio');
1660    }
1661    if (recordEvent.length > 0) {
1662      recordArgs += ' --events ' + recordEvent.toString();
1663    }
1664    recordArgs += ' --duration ' + this.recordSetting?.maxDur;
1665    if (systemConfig?.process && !systemConfig?.process.includes('ALL') && systemConfig?.process.length > 0) {
1666      recordArgs = recordArgs + ' --pids ' + systemConfig?.process;
1667    }
1668    recordArgs += ' --max_stack_depth ' + systemConfig?.unWindLevel;
1669    let systemPluginConfig: FileSystemConfig = {
1670      cmdLine: recordArgs,
1671      outfileName: '/data/local/tmp/ebpf.data',
1672    };
1673    let ebpfPluginConfig: ProfilerPluginConfig<FileSystemConfig> = {
1674      pluginName: 'hiebpf-plugin',
1675      sampleInterval: 1000,
1676      configData: systemPluginConfig,
1677    };
1678    return ebpfPluginConfig;
1679  }
1680
1681  private createNativePluginConfig(reportingFrequency: number) {
1682    let appProcess = this.spAllocations!.appProcess;
1683    let re = /^[0-9]+.?[0-9]*/;
1684    let pid = 0;
1685    let processName = '';
1686    let processId = '';
1687    if (appProcess.indexOf('(') != -1) {
1688      processId = appProcess.slice(appProcess.lastIndexOf('(') + 1, appProcess.lastIndexOf(')'));
1689    } else {
1690      processId = appProcess;
1691    }
1692    if (re.test(processId)) {
1693      pid = Number(processId);
1694    } else {
1695      processName = appProcess;
1696    }
1697    let nativeConfig: NativeHookConfig = {
1698      pid: pid,
1699      saveFile: false,
1700      fileName: '',
1701      filterSize: this.spAllocations!.filter,
1702      smbPages: this.spAllocations!.shared,
1703      maxStackDepth: this.spAllocations!.unwind,
1704      processName: processName,
1705      stringCompressed: true,
1706      fpUnwind: this.spAllocations!.fp_unwind,
1707      blocked: true,
1708    };
1709    if (Number(SpRecordTrace.selectVersion) >= 4.0) {
1710      nativeConfig.callframeCompress = true;
1711      nativeConfig.recordAccurately = this.spAllocations!.record_accurately;
1712      nativeConfig.offlineSymbolization = this.spAllocations!.offline_symbolization;
1713      if (this.spAllocations!.record_statistics) {
1714        nativeConfig.statisticsInterval = this.spAllocations!.statistics_interval;
1715      }
1716    }
1717    let nativePluginConfig: ProfilerPluginConfig<NativeHookConfig> = {
1718      pluginName: 'nativehook',
1719      sampleInterval: reportingFrequency * 1000,
1720      configData: nativeConfig,
1721    };
1722    return nativePluginConfig;
1723  }
1724
1725  private createMemoryPluginConfig(
1726    reportingFrequency: number,
1727    hasmemoryConfig: boolean,
1728    hasMonitorMemory: boolean,
1729    hasSmaps: boolean
1730  ) {
1731    let memoryconfig: MemoryConfig = {
1732      reportProcessTree: false,
1733      reportSysmemMemInfo: false,
1734      sysMeminfoCounters: [],
1735      reportSysmemVmemInfo: false,
1736      sysVmeminfoCounters: [],
1737      reportProcessMemInfo: false,
1738      reportAppMemInfo: false,
1739      reportAppMemByMemoryService: false,
1740      pid: [],
1741    };
1742    if (hasmemoryConfig || hasMonitorMemory) {
1743      memoryconfig.reportProcessTree = true;
1744      memoryconfig.reportSysmemMemInfo = true;
1745      memoryconfig.reportSysmemVmemInfo = true;
1746      memoryconfig.reportProcessMemInfo = true;
1747    }
1748    if (hasSmaps) {
1749      memoryconfig.reportSmapsMemInfo = true;
1750      let pid = Number(this.spVmTracker?.process);
1751      memoryconfig.pid.push(pid);
1752    }
1753    if (hasMonitorMemory) {
1754      SpRecordTrace.ABALITY_MEM_INFO.forEach((va) => {
1755        memoryconfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
1756      });
1757    }
1758    this.probesConfig!.memoryConfig.forEach((value) => {
1759      if (value.indexOf('Kernel meminfo') != -1) {
1760        if (hasMonitorMemory) {
1761          memoryconfig.sysMeminfoCounters = [];
1762        }
1763        SpRecordTrace.MEM_INFO.forEach((va) => {
1764          memoryconfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
1765        });
1766      }
1767      if (value.indexOf('Virtual memory stats') != -1) {
1768        SpRecordTrace.VMEM_INFO.forEach((me) => {
1769          memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
1770        });
1771        SpRecordTrace.VMEM_INFO_SECOND.forEach((me) => {
1772          memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
1773        });
1774        SpRecordTrace.VMEM_INFO_THIRD.forEach((me) => {
1775          memoryconfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
1776        });
1777      }
1778    });
1779    let profilerPluginConfig: ProfilerPluginConfig<MemoryConfig> = {
1780      pluginName: 'memory-plugin',
1781      sampleInterval: reportingFrequency * 1000,
1782      configData: memoryconfig,
1783    };
1784    SpRecordTrace.appendSerialize(profilerPluginConfig);
1785    return profilerPluginConfig;
1786  }
1787
1788  private createJsHeapConfig() {
1789    let process = this.spJsHeap!.process;
1790    let re = /^[0-9]+.?[0-9]*/;
1791    let pid = 0;
1792    let processId = '';
1793    if (process.indexOf('(') != -1) {
1794      processId = process.slice(process.lastIndexOf('(') + 1, process.lastIndexOf(')'));
1795    } else {
1796      processId = process;
1797    }
1798    if (re.test(processId)) {
1799      pid = Number(processId);
1800    }
1801    let arkTSConfig: ArkTSConfig = {
1802      pid: pid,
1803      type: this.spJsHeap!.radioBoxType,
1804      interval: this.spJsHeap!.intervalValue,
1805      capture_numeric_value: this.spJsHeap!.grabNumeric,
1806      track_allocations: this.spJsHeap!.grabAllocations,
1807    };
1808    let arkTSPluginConfig: ProfilerPluginConfig<ArkTSConfig> = {
1809      pluginName: 'arkts-plugin',
1810      sampleInterval: 5000,
1811      configData: arkTSConfig,
1812    };
1813
1814    return arkTSPluginConfig;
1815  }
1816
1817  private createFpsPluginConfig() {
1818    let fpsConfig: FpsConfig = {
1819      reportFps: true,
1820    };
1821    let fpsPlugin: ProfilerPluginConfig<FpsConfig> = {
1822      pluginName: 'hidump-plugin',
1823      sampleInterval: 1000,
1824      configData: fpsConfig,
1825    };
1826    SpRecordTrace.appendSerialize(fpsPlugin);
1827    return fpsPlugin;
1828  }
1829
1830  private createHiSystemEventPluginConfig(appName: string) {
1831    let hiSystemEventConfig: HiSystemEventConfig = {
1832      msg: 'hisysevent-plugin',
1833      processName: appName,
1834    };
1835    let hiSystemEventPlugin: ProfilerPluginConfig<HiSystemEventConfig> = {
1836      pluginName: 'hisysevent-plugin',
1837      configData: hiSystemEventConfig,
1838    };
1839    SpRecordTrace.appendSerialize(hiSystemEventPlugin);
1840    return hiSystemEventPlugin;
1841  }
1842
1843  private createHtracePluginConfig() {
1844    let tracePluginConfig: TracePluginConfig = {
1845      ftraceEvents: this.createTraceEvents(this.probesConfig!.traceConfig),
1846      hitraceCategories: [],
1847      hitraceApps: [],
1848      bufferSizeKb: this.probesConfig!.ftraceBufferSize,
1849      flushIntervalMs: 1000,
1850      flushThresholdKb: 4096,
1851      parseKsyms: true,
1852      clock: 'boot',
1853      tracePeriodMs: 200,
1854      rawDataPrefix: '',
1855      traceDurationMs: 0,
1856      debugOn: false,
1857      hitraceTime: this.recordSetting!.maxDur,
1858    };
1859    if (this.probesConfig!.traceEvents.length > 0) {
1860      tracePluginConfig.hitraceCategories = this.probesConfig!.traceEvents;
1861    }
1862    let htraceProfilerPluginConfig: ProfilerPluginConfig<TracePluginConfig> = {
1863      pluginName: 'ftrace-plugin',
1864      sampleInterval: 1000,
1865      configData: tracePluginConfig,
1866    };
1867    SpRecordTrace.appendSerialize(htraceProfilerPluginConfig);
1868    return htraceProfilerPluginConfig;
1869  }
1870
1871  static appendSerialize(profilerPluginConfig: ProfilerPluginConfig<{}>) {
1872    if (Number(SpRecordTrace.selectVersion) >= 4.0) {
1873    }
1874  }
1875
1876  private createSdkConfig() {
1877    let gpuConfig = this.spSdkConfig!.getGpuConfig();
1878    let gpuPluginConfig: ProfilerPluginConfig<{}> = {
1879      pluginName: this.spSdkConfig!.getPlugName(),
1880      sampleInterval: this.spSdkConfig!.getSampleInterval(),
1881      configData: gpuConfig,
1882    };
1883    SpRecordTrace.appendSerialize(gpuPluginConfig);
1884    return gpuPluginConfig;
1885  }
1886
1887  freshConfigMenuDisable(disable: boolean) {
1888    let querySelectors = this.shadowRoot?.querySelectorAll<LitMainMenuItem>('lit-main-menu-item');
1889    querySelectors!.forEach((item) => {
1890      if (disable) {
1891        item.style.pointerEvents = 'none';
1892      } else {
1893        item.style.pointerEvents = 'auto';
1894      }
1895      item.disabled = disable;
1896    });
1897  }
1898
1899  public startRefreshDeviceList() {
1900    if (this.refreshDeviceTimer === undefined) {
1901      this.refreshDeviceTimer = window.setInterval(() => {
1902        this.refreshDeviceList();
1903      }, 5000);
1904    }
1905  }
1906
1907  buttonDisable(disable: boolean) {
1908    if (disable) {
1909      this.disconnectButton!.style.pointerEvents = 'none';
1910      this.recordButtonText!.textContent = this.stop;
1911      this.addButton!.style.pointerEvents = 'none';
1912      this.deviceSelect!.style.pointerEvents = 'none';
1913      this.deviceVersion!.style.pointerEvents = 'none';
1914    } else {
1915      this.recordButtonText!.textContent = this.record;
1916      this.disconnectButton!.style.pointerEvents = 'auto';
1917      this.addButton!.style.pointerEvents = 'auto';
1918      this.deviceSelect!.style.pointerEvents = 'auto';
1919      this.deviceVersion!.style.pointerEvents = 'auto';
1920    }
1921  }
1922
1923  freshMenuItemsStatus(currentValue: string) {
1924    let litMainMenuGroup = this.shadowRoot?.querySelector<LitMainMenuGroup>('lit-main-menu-group');
1925    let litMainMenuItemNodeListOf = litMainMenuGroup!.querySelectorAll<LitMainMenuItem>('lit-main-menu-item');
1926    litMainMenuItemNodeListOf.forEach((item) => {
1927      item.back = item.title == currentValue;
1928    });
1929  }
1930
1931  synchronizeDeviceList() {
1932    this.deviceSelect!.innerHTML = '';
1933    if (SpRecordTrace.serialNumber != '') {
1934      let option = document.createElement('option');
1935      option.className = 'select';
1936      option.selected = true;
1937      option.value = SpRecordTrace.serialNumber;
1938      option.textContent = SpRecordTrace.serialNumber;
1939      this.deviceSelect!.appendChild(option);
1940      this.recordButton!.hidden = false;
1941      this.disconnectButton!.hidden = false;
1942      if (SpRecordTrace.selectVersion && SpRecordTrace.selectVersion != '') {
1943        this.setDeviceVersionSelect(SpRecordTrace.selectVersion);
1944      }
1945    }
1946  }
1947}
1948