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 {
17  ArkTSConfig,
18  CreateSessionRequest, FFRTConfig,
19  FpsConfig,
20  HiebpfConfig,
21  HilogConfig,
22  HiperfPluginConfig,
23  levelFromJSON,
24  MemoryConfig,
25  NativeHookConfig,
26  ProfilerSessionConfig,
27  ProfilerSessionConfigBufferConfig,
28  ProfilerSessionConfigBufferConfigPolicy,
29  ProfilerSessionConfigMode,
30  sysMeminfoTypeFromJSON,
31  sysVMeminfoTypeFromJSON,
32  TracePluginConfig,
33} from './setting/bean/ProfilerServiceTypes';
34import { SpRecordSetting } from './setting/SpRecordSetting';
35import { SpVmTracker } from './setting/SpVmTracker';
36import { SpProbesConfig } from './setting/SpProbesConfig';
37import { info } from '../../log/Log';
38import { SpAllocations } from './setting/SpAllocations';
39import { SpApplication } from '../SpApplication';
40import { PerfConfig, SpRecordPerf } from './setting/SpRecordPerf';
41import { SpFileSystem } from './setting/SpFileSystem';
42import { SpSdkConfig } from './setting/SpSdkConfig';
43import { SpHisysEvent } from './setting/SpHisysEvent';
44import { SpArkTs } from './setting/SpArkTs';
45import { SpHilogRecord } from './setting/SpHilogRecord';
46import { SpFFRTConfig } from './setting/SpFFRTConfig';
47import { SpXPowerRecord } from './setting/SpXPowerRecord';
48
49export const MEM_INFO = [
50  'MEMINFO_ACTIVE',
51  'MEMINFO_ACTIVE_ANON',
52  'MEMINFO_ACTIVE_FILE',
53  'MEMINFO_ANON_PAGES',
54  'MEMINFO_BUFFERS',
55  'MEMINFO_CACHED',
56  'MEMINFO_CMA_FREE',
57  'MEMINFO_CMA_TOTAL',
58  'MEMINFO_COMMIT_LIMIT',
59  'MEMINFO_COMMITED_AS',
60  'MEMINFO_DIRTY',
61  'MEMINFO_INACTIVE',
62  'MEMINFO_INACTIVE_ANON',
63  'MEMINFO_INACTIVE_FILE',
64  'MEMINFO_KERNEL_STACK',
65  'MEMINFO_MAPPED',
66  'MEMINFO_MEM_AVAILABLE',
67  'MEMINFO_MEM_FREE',
68  'MEMINFO_MEM_TOTAL',
69  'MEMINFO_MLOCKED',
70  'MEMINFO_PAGE_TABLES',
71  'MEMINFO_SHMEM',
72  'MEMINFO_SLAB',
73  'MEMINFO_SLAB_RECLAIMABLE',
74  'MEMINFO_SLAB_UNRECLAIMABLE',
75  'MEMINFO_SWAP_CACHED',
76  'MEMINFO_SWAP_FREE',
77  'MEMINFO_SWAP_TOTAL',
78  'MEMINFO_UNEVICTABLE',
79  'MEMINFO_VMALLOC_CHUNK',
80  'MEMINFO_VMALLOC_TOTAL',
81  'MEMINFO_VMALLOC_USED',
82  'MEMINFO_WRITEBACK',
83  'MEMINFO_KERNEL_RECLAIMABLE',
84  'PMEM_ACTIVE_PURG',
85  'PMEM_INACTIVE_PURG',
86  'PMEM_PINED_PURG',
87];
88
89export const VMEM_INFO = [
90  'VMEMINFO_UNSPECIFIED',
91  'VMEMINFO_NR_FREE_PAGES',
92  'VMEMINFO_NR_ALLOC_BATCH',
93  'VMEMINFO_NR_INACTIVE_ANON',
94  'VMEMINFO_NR_ACTIVE_ANON',
95  'VMEMINFO_NR_INACTIVE_FILE',
96  'VMEMINFO_NR_ACTIVE_FILE',
97  'VMEMINFO_NR_UNEVICTABLE',
98  'VMEMINFO_NR_MLOCK',
99  'VMEMINFO_NR_ANON_PAGES',
100  'VMEMINFO_NR_MAPPED',
101  'VMEMINFO_NR_FILE_PAGES',
102  'VMEMINFO_NR_DIRTY',
103  'VMEMINFO_NR_WRITEBACK',
104  'VMEMINFO_NR_SLAB_RECLAIMABLE',
105  'VMEMINFO_NR_SLAB_UNRECLAIMABLE',
106  'VMEMINFO_NR_PAGE_TABLE_PAGES',
107  'VMEMINFO_NR_KERNEL_STACK',
108  'VMEMINFO_NR_OVERHEAD',
109  'VMEMINFO_NR_UNSTABLE',
110  'VMEMINFO_NR_BOUNCE',
111  'VMEMINFO_NR_VMSCAN_WRITE',
112  'VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM',
113  'VMEMINFO_NR_WRITEBACK_TEMP',
114  'VMEMINFO_NR_ISOLATED_ANON',
115  'VMEMINFO_NR_ISOLATED_FILE',
116  'VMEMINFO_NR_SHMEM',
117  'VMEMINFO_NR_DIRTIED',
118  'VMEMINFO_NR_WRITTEN',
119  'VMEMINFO_NR_PAGES_SCANNED',
120  'VMEMINFO_WORKINGSET_REFAULT',
121  'VMEMINFO_WORKINGSET_ACTIVATE',
122  'VMEMINFO_WORKINGSET_NODERECLAIM',
123  'VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES',
124  'VMEMINFO_NR_FREE_CMA',
125  'VMEMINFO_NR_SWAPCACHE',
126  'VMEMINFO_NR_DIRTY_THRESHOLD',
127  'VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD',
128  'VMEMINFO_PGPGIN',
129  'VMEMINFO_PGPGOUT',
130  'VMEMINFO_PGPGOUTCLEAN',
131  'VMEMINFO_PSWPIN',
132  'VMEMINFO_PSWPOUT',
133  'VMEMINFO_PGALLOC_DMA',
134];
135
136export const VMEM_INFO_SECOND = [
137  'VMEMINFO_PGALLOC_NORMAL',
138  'VMEMINFO_PGALLOC_MOVABLE',
139  'VMEMINFO_PGFREE',
140  'VMEMINFO_PGACTIVATE',
141  'VMEMINFO_PGDEACTIVATE',
142  'VMEMINFO_PGFAULT',
143  'VMEMINFO_PGMAJFAULT',
144  'VMEMINFO_PGREFILL_DMA',
145  'VMEMINFO_PGREFILL_NORMAL',
146  'VMEMINFO_PGREFILL_MOVABLE',
147  'VMEMINFO_PGSTEAL_KSWAPD_DMA',
148  'VMEMINFO_PGSTEAL_KSWAPD_NORMAL',
149  'VMEMINFO_PGSTEAL_KSWAPD_MOVABLE',
150  'VMEMINFO_PGSTEAL_DIRECT_DMA',
151  'VMEMINFO_PGSTEAL_DIRECT_NORMAL',
152  'VMEMINFO_PGSTEAL_DIRECT_MOVABLE',
153  'VMEMINFO_PGSCAN_KSWAPD_DMA',
154  'VMEMINFO_PGSCAN_KSWAPD_NORMAL',
155  'VMEMINFO_PGSCAN_KSWAPD_MOVABLE',
156  'VMEMINFO_PGSCAN_DIRECT_DMA',
157  'VMEMINFO_PGSCAN_DIRECT_NORMAL',
158  'VMEMINFO_PGSCAN_DIRECT_MOVABLE',
159  'VMEMINFO_PGSCAN_DIRECT_THROTTLE',
160  'VMEMINFO_PGINODESTEAL',
161  'VMEMINFO_SLABS_SCANNED',
162  'VMEMINFO_KSWAPD_INODESTEAL',
163  'VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY',
164  'VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY',
165  'VMEMINFO_PAGEOUTRUN',
166  'VMEMINFO_ALLOCSTALL',
167  'VMEMINFO_PGROTATED',
168  'VMEMINFO_DROP_PAGECACHE',
169  'VMEMINFO_DROP_SLAB',
170  'VMEMINFO_PGMIGRATE_SUCCESS',
171  'VMEMINFO_PGMIGRATE_FAIL',
172  'VMEMINFO_COMPACT_MIGRATE_SCANNED',
173  'VMEMINFO_COMPACT_FREE_SCANNED',
174  'VMEMINFO_COMPACT_ISOLATED',
175  'VMEMINFO_COMPACT_STALL',
176  'VMEMINFO_COMPACT_FAIL',
177  'VMEMINFO_COMPACT_SUCCESS',
178  'VMEMINFO_COMPACT_DAEMON_WAKE',
179  'VMEMINFO_UNEVICTABLE_PGS_CULLED',
180  'VMEMINFO_UNEVICTABLE_PGS_SCANNED',
181  'VMEMINFO_UNEVICTABLE_PGS_RESCUED',
182  'VMEMINFO_UNEVICTABLE_PGS_MLOCKED',
183  'VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED',
184];
185
186export const VMEM_INFO_THIRD = [
187  'VMEMINFO_UNEVICTABLE_PGS_CLEARED',
188  'VMEMINFO_UNEVICTABLE_PGS_STRANDED',
189  'VMEMINFO_NR_ZSPAGES',
190  'VMEMINFO_NR_ION_HEAP',
191  'VMEMINFO_NR_GPU_HEAP',
192  'VMEMINFO_ALLOCSTALL_DMA',
193  'VMEMINFO_ALLOCSTALL_MOVABLE',
194  'VMEMINFO_ALLOCSTALL_NORMAL',
195  'VMEMINFO_COMPACT_DAEMON_FREE_SCANNED',
196  'VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED',
197  'VMEMINFO_NR_FASTRPC',
198  'VMEMINFO_NR_INDIRECTLY_RECLAIMABLE',
199  'VMEMINFO_NR_ION_HEAP_POOL',
200  'VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE',
201  'VMEMINFO_NR_SHADOW_CALL_STACK_BYTES',
202  'VMEMINFO_NR_SHMEM_HUGEPAGES',
203  'VMEMINFO_NR_SHMEM_PMDMAPPED',
204  'VMEMINFO_NR_UNRECLAIMABLE_PAGES',
205  'VMEMINFO_NR_ZONE_ACTIVE_ANON',
206  'VMEMINFO_NR_ZONE_ACTIVE_FILE',
207  'VMEMINFO_NR_ZONE_INACTIVE_ANON',
208  'VMEMINFO_NR_ZONE_INACTIVE_FILE',
209  'VMEMINFO_NR_ZONE_UNEVICTABLE',
210  'VMEMINFO_NR_ZONE_WRITE_PENDING',
211  'VMEMINFO_OOM_KILL',
212  'VMEMINFO_PGLAZYFREE',
213  'VMEMINFO_PGLAZYFREED',
214  'VMEMINFO_PGREFILL',
215  'VMEMINFO_PGSCAN_DIRECT',
216  'VMEMINFO_PGSCAN_KSWAPD',
217  'VMEMINFO_PGSKIP_DMA',
218  'VMEMINFO_PGSKIP_MOVABLE',
219  'VMEMINFO_PGSKIP_NORMAL',
220  'VMEMINFO_PGSTEAL_DIRECT',
221  'VMEMINFO_PGSTEAL_KSWAPD',
222  'VMEMINFO_SWAP_RA',
223  'VMEMINFO_SWAP_RA_HIT',
224  'VMEMINFO_WORKINGSET_RESTORE',
225];
226// sys.mem.total   sys.mem.free sys.mem.buffers sys.mem.cached  sys.mem.shmem  sys.mem.slab  sys.mem.swap.total
227// sys.mem.swap.free sys.mem.mapped  sys.mem.vmalloc.used  sys.mem.page.tables  sys.mem.kernel.stack
228// sys.mem.active sys.mem.inactive  sys.mem.unevictable  sys.mem.vmalloc.total sys.mem.slab.unreclaimable
229// sys.mem.cma.total sys.mem.cma.free
230export const ABALITY_MEM_INFO = [
231  'MEMINFO_MEM_TOTAL',
232  'MEMINFO_MEM_FREE',
233  'MEMINFO_BUFFERS',
234  'MEMINFO_CACHED',
235  'MEMINFO_SHMEM',
236  'MEMINFO_SLAB',
237  'MEMINFO_SWAP_TOTAL',
238  'MEMINFO_SWAP_FREE',
239  'MEMINFO_MAPPED',
240  'MEMINFO_VMALLOC_USED',
241  'MEMINFO_PAGE_TABLES',
242  'MEMINFO_KERNEL_STACK',
243  'MEMINFO_ACTIVE',
244  'MEMINFO_INACTIVE',
245  'MEMINFO_UNEVICTABLE',
246  'MEMINFO_VMALLOC_TOTAL',
247  'MEMINFO_SLAB_UNRECLAIMABLE',
248  'MEMINFO_CMA_TOTAL',
249  'MEMINFO_CMA_FREE',
250  'MEMINFO_KERNEL_RECLAIMABLE',
251  'PMEM_ACTIVE_PURG',
252  'PMEM_INACTIVE_PURG',
253  'PMEM_PINED_PURG',
254];
255
256export const schedulingEvents = [
257  'sched/sched_switch',
258  'power/suspend_resume',
259  'sched/sched_wakeup',
260  'sched/sched_wakeup_new',
261  'sched/sched_waking',
262  'sched/sched_process_exit',
263  'sched/sched_process_free',
264  'task/task_newtask',
265  'task/task_rename',
266];
267
268export const powerEvents = [
269  'regulator/regulator_set_voltage',
270  'regulator/regulator_set_voltage_complete',
271  'power/clock_enable',
272  'power/clock_disable',
273  'power/clock_set_rate',
274  'power/suspend_resume',
275];
276
277export const cpuFreqEvents = ['power/cpu_frequency', 'power/cpu_idle', 'power/suspend_resume'];
278
279export const sysCallsEvents = ['raw_syscalls/sys_enter', 'raw_syscalls/sys_exit'];
280
281export const highFrequencyEvents = [
282  'mm_event/mm_event_record',
283  'kmem/rss_stat',
284  'ion/ion_stat',
285  'dmabuf_heap/dma_heap_stat',
286  'kmem/ion_heap_grow',
287  'kmem/ion_heap_shrink',
288];
289
290export const advancedConfigEvents = [
291  'sched/sched_switch',
292  'sched/sched_wakeup',
293  'sched/sched_wakeup_new',
294  'sched/sched_waking',
295  'sched/sched_process_exit',
296  'sched/sched_process_free',
297  'irq/irq_handler_entry',
298  'irq/irq_handler_exit',
299  'irq/softirq_entry',
300  'irq/softirq_exit',
301  'irq/softirq_raise',
302  'power/clock_disable',
303  'power/clock_enable',
304  'power/clock_set_rate',
305  'power/cpu_frequency',
306  'power/cpu_idle',
307  'clk/clk_disable',
308  'clk/clk_disable_complete',
309  'clk/clk_enable',
310  'clk/clk_enable_complete',
311  'clk/clk_set_rate',
312  'clk/clk_set_rate_complete',
313  'binder/binder_transaction',
314  'binder/binder_transaction_alloc_buf',
315  'binder/binder_transaction_received',
316  'binder/binder_lock',
317  'binder/binder_locked',
318  'binder/binder_unlock',
319  'workqueue/workqueue_execute_start',
320  'workqueue/workqueue_execute_end',
321  'oom/oom_score_adj_update',
322  'ftrace/print',
323];
324
325export function createSessionRequest(recordSetting: SpRecordSetting): CreateSessionRequest {
326  let bufferConfig: ProfilerSessionConfigBufferConfig = {
327    pages: recordSetting.bufferSize * 256,
328    policy: ProfilerSessionConfigBufferConfigPolicy.RECYCLE,
329  };
330  let sessionConfig: ProfilerSessionConfig = {
331    buffers: [bufferConfig],
332    sessionMode: ProfilerSessionConfigMode.OFFLINE,
333    resultMaxSize: 0,
334    keepAliveTime: 0,
335  };
336  return {
337    requestId: 1,
338    sessionConfig: sessionConfig,
339    pluginConfigs: [],
340  };
341}
342
343export function createMemoryPluginConfig(
344  reportingFrequency: number,
345  spVmTracker: SpVmTracker,
346  probesConfig: SpProbesConfig,
347  request: CreateSessionRequest
348): void {
349  let hasSamp = spVmTracker!.startSamp && spVmTracker!.process !== '';
350  if (probesConfig!.memoryConfig.length > 0 || hasMonitorMemory || hasSamp) {
351    let memoryConfig = initMemoryPluginConfig(hasSamp, spVmTracker, probesConfig);
352    if (hasMonitorMemory) {
353      ABALITY_MEM_INFO.forEach((va) => {
354        memoryConfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
355      });
356    }
357    probesConfig!.memoryConfig.forEach((value) => {
358      if (value.indexOf('Kernel meminfo') !== -1) {
359        if (hasMonitorMemory) {
360          memoryConfig.sysMeminfoCounters = [];
361        }
362        MEM_INFO.forEach((va) => {
363          memoryConfig.sysMeminfoCounters.push(sysMeminfoTypeFromJSON(va));
364        });
365      }
366      if (value.indexOf('Virtual memory stats') !== -1) {
367        VMEM_INFO.forEach((me) => {
368          memoryConfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
369        });
370        VMEM_INFO_SECOND.forEach((me) => {
371          memoryConfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
372        });
373        VMEM_INFO_THIRD.forEach((me) => {
374          memoryConfig.sysVmeminfoCounters.push(sysVMeminfoTypeFromJSON(me));
375        });
376      }
377    });
378    request.pluginConfigs.push({
379      pluginName: 'memory-plugin',
380      sampleInterval: reportingFrequency * 1000,
381      configData: memoryConfig,
382    });
383  }
384}
385
386function initMemoryPluginConfig(
387  hasSamp: boolean,
388  spVmTracker: SpVmTracker,
389  probesConfig: SpProbesConfig
390): MemoryConfig {
391  let memoryConfig: MemoryConfig = {
392    reportProcessTree: false,
393    reportSysmemMemInfo: false,
394    sysMeminfoCounters: [],
395    reportSysmemVmemInfo: false,
396    sysVmeminfoCounters: [],
397    reportProcessMemInfo: false,
398    reportAppMemInfo: false,
399    reportAppMemByMemoryService: false,
400    pid: [],
401  };
402  if (probesConfig!.memoryConfig.length > 0 || hasMonitorMemory) {
403    memoryConfig.reportProcessTree = true;
404    memoryConfig.reportSysmemMemInfo = true;
405    memoryConfig.reportSysmemVmemInfo = true;
406    memoryConfig.reportProcessMemInfo = true;
407  }
408  if (spVmTracker!.startSamp) {
409    memoryConfig.reportProcessMemInfo = true;
410  }
411  if (hasSamp || hasMonitorMemory) {
412    memoryConfig.reportPurgeableAshmemInfo = true;
413    memoryConfig.reportDmaMemInfo = true;
414    memoryConfig.reportGpuMemInfo = true;
415  }
416  if (hasSamp) {
417    memoryConfig.reportSmapsMemInfo = true;
418    memoryConfig.reportGpuDumpInfo = true;
419    let pid = Number(spVmTracker?.process);
420    memoryConfig.pid.push(pid);
421  }
422  return memoryConfig;
423}
424
425export function createHTracePluginConfig(probesConfig: SpProbesConfig, request: CreateSessionRequest): void {
426  if (probesConfig!.traceConfig.length > 0 && probesConfig!.traceConfig.find((value) => value !== 'FPS')) {
427    let tracePluginConfig: TracePluginConfig = {
428      ftraceEvents: createTraceEvents(probesConfig!.traceConfig),
429      hitraceCategories: [],
430      hitraceApps: [],
431      bufferSizeKb: probesConfig!.ftraceBufferSize,
432      flushIntervalMs: 1000,
433      flushThresholdKb: 4096,
434      parseKsyms: true,
435      clock: 'boot',
436      tracePeriodMs: 200,
437      rawDataPrefix: '',
438      traceDurationMs: 0,
439      debugOn: false,
440    };
441    if (probesConfig!.traceEvents.length > 0) {
442      tracePluginConfig.hitraceCategories = probesConfig!.traceEvents;
443    }
444    request.pluginConfigs.push({
445      pluginName: 'ftrace-plugin',
446      sampleInterval: 1000,
447      configData: tracePluginConfig,
448    });
449  }
450}
451
452export function createFpsPluginConfig(probesConfig: SpProbesConfig, request: CreateSessionRequest): void {
453  let fpsConfig: FpsConfig = {
454    reportFps: true,
455  };
456  if (probesConfig!.traceConfig.length > 0 && probesConfig!.traceConfig.indexOf('FPS') !== -1) {
457    request.pluginConfigs.push({
458      pluginName: 'hidump-plugin',
459      sampleInterval: 1000,
460      configData: fpsConfig,
461    });
462  }
463}
464
465export function createMonitorPlugin(probesConfig: SpProbesConfig, request: CreateSessionRequest): void {
466  hasMonitorMemory = probesConfig.recordAbility;
467  if (!probesConfig.recordAbility) {
468    return;
469  }
470  let cpuPlugin = {
471    pluginName: 'cpu-plugin',
472    sampleInterval: 1000,
473    configData: {
474      pid: 0,
475      reportProcessInfo: true,
476    },
477  };
478  let processPlugin = {
479    pluginName: 'process-plugin',
480    sampleInterval: 1000,
481    configData: {
482      report_process_tree: true,
483      report_cpu: true,
484      report_diskio: true,
485      report_pss: true,
486    },
487  };
488  let diskIoPlugin = {
489    pluginName: 'diskio-plugin',
490    sampleInterval: 1000,
491    configData: {
492      reportIoStats: 'IO_REPORT',
493    },
494  };
495  let netWorkPlugin = {
496    pluginName: 'network-plugin',
497    sampleInterval: 1000,
498    configData: {},
499  };
500  request.pluginConfigs.push(processPlugin);
501  request.pluginConfigs.push(cpuPlugin);
502  request.pluginConfigs.push(diskIoPlugin);
503  request.pluginConfigs.push(netWorkPlugin);
504}
505
506export function createNativePluginConfig(
507  reportingFrequency: number,
508  spAllocations: SpAllocations,
509  selectVersion: string | null,
510  request: CreateSessionRequest
511): void {
512  if (spAllocations!.appProcess !== '' && spAllocations!.startSamp) {
513    let nativeConfig = initNativePluginConfig(spAllocations, selectVersion);
514    let maxProcessSize = 4;
515    if (selectVersion !== undefined && selectVersion !== '3.2') {
516      nativeConfig.callframeCompress = true;
517      nativeConfig.recordAccurately = spAllocations!.record_accurately;
518      nativeConfig.offlineSymbolization = spAllocations!.offline_symbolization;
519      if (spAllocations!.record_statistics) {
520        nativeConfig.statisticsInterval = spAllocations!.statistics_interval;
521      }
522      nativeConfig.startupMode = spAllocations!.startup_mode;
523      if (spAllocations!.response_lib_mode) {
524        nativeConfig.responseLibraryMode = spAllocations!.response_lib_mode;
525        maxProcessSize = 8;
526      }
527      if (spAllocations && spAllocations.sample_interval) {
528        if (spAllocations.record_statistics) {
529          nativeConfig.sampleInterval = spAllocations.sample_interval;
530        } else {
531          nativeConfig.mallocFreeMatchingInterval = spAllocations.sample_interval;
532        }
533      }
534      nativeConfig.jsStackReport = spAllocations!.recordJsStack ? 1 : 0;
535      if (spAllocations!.recordJsStack) {
536        nativeConfig.maxJsStackDepth = spAllocations!.max_js_stack_depth;
537        nativeConfig.filterNapiName = spAllocations!.filter_napi_name;
538      }
539    }
540    if (spAllocations!.expandPids.length > 1) {
541      nativeConfig.expandPids = spAllocations!.expandPids.splice(0, maxProcessSize);
542    }
543    request.pluginConfigs.push({
544      pluginName: 'nativehook',
545      sampleInterval: reportingFrequency * 1000,
546      configData: nativeConfig,
547    });
548  }
549}
550
551function initNativePluginConfig(spAllocations: SpAllocations, selectVersion: string | null): NativeHookConfig {
552  let appProcess = spAllocations!.appProcess;
553  let processName = '';
554  let processId = '';
555  if (spAllocations!.startup_mode && selectVersion !== '3.2') {
556    processName = appProcess;
557  } else {
558    if (appProcess.indexOf('(') !== -1) {
559      processId = appProcess.slice(appProcess.lastIndexOf('(') + 1, appProcess.lastIndexOf(')'));
560    } else {
561      processId = appProcess;
562    }
563    if (/^[0-9]+.?[0-9]*/.test(processId)) {
564      let pid = Number(processId);
565    } else {
566      processName = appProcess;
567    }
568  }
569  let nativeConfig: NativeHookConfig;
570  if (spAllocations!.expandPids.length === 1) {
571    nativeConfig = {
572      pid: spAllocations!.expandPids[0],
573      saveFile: false,
574      fileName: '',
575      filterSize: spAllocations!.filter,
576      smbPages: spAllocations!.shared,
577      maxStackDepth: spAllocations!.unwind,
578      processName: processName,
579      stringCompressed: true,
580      fpUnwind: spAllocations!.fp_unwind,
581      blocked: true,
582    };
583  } else {
584    nativeConfig = {
585      saveFile: false,
586      fileName: '',
587      filterSize: spAllocations!.filter,
588      smbPages: spAllocations!.shared,
589      maxStackDepth: spAllocations!.unwind,
590      processName: processName,
591      stringCompressed: true,
592      fpUnwind: spAllocations!.fp_unwind,
593      blocked: true,
594    };
595  }
596  return nativeConfig;
597}
598
599function initHiPerfConfig(perfConfig: PerfConfig | undefined, recordArgs: string): string {
600  if (!perfConfig) {
601    return '';
602  }
603  if (perfConfig.cpu && !perfConfig.cpu.includes('ALL') && perfConfig.cpu.length > 0) {
604    recordArgs = `${recordArgs} -c ${perfConfig.cpu}`;
605  }
606  if (perfConfig.cpuPercent !== 0) {
607    recordArgs = `${recordArgs} --cpu-limit ${perfConfig.cpuPercent}`;
608  }
609  if (perfConfig.eventList && !perfConfig.eventList.includes('NONE') && perfConfig.eventList.length > 0) {
610    recordArgs = `${recordArgs} -e ${perfConfig.eventList}`;
611    if (perfConfig.isOffCpu) {
612      recordArgs = `${recordArgs},sched:sched_waking`;
613    }
614  } else {
615    recordArgs = `${recordArgs} -e hw-cpu-cycles`;
616    if (perfConfig.isOffCpu) {
617      recordArgs = `${recordArgs},sched:sched_waking`;
618    }
619  }
620  if (perfConfig.callStack !== 'none') {
621    recordArgs = `${recordArgs} --call-stack ${perfConfig.callStack}`;
622  }
623  if (perfConfig.branch !== 'none') {
624    recordArgs = `${recordArgs} -j ${perfConfig.branch}`;
625  }
626  if (perfConfig.clockType) {
627    recordArgs = `${recordArgs} --clockid ${perfConfig.clockType}`;
628  }
629  if (perfConfig.isOffCpu) {
630    recordArgs = `${recordArgs} --offcpu`;
631  }
632  if (perfConfig?.isKernelChain) {
633    recordArgs = `${recordArgs} --kernel-callchain`;
634  }
635  if (perfConfig.noInherit) {
636    recordArgs = `${recordArgs} --no-inherit`;
637  }
638  if (perfConfig.mmap) {
639    recordArgs = `${recordArgs} -m ${perfConfig.mmap}`;
640  }
641  return recordArgs;
642}
643
644export function createHiPerfConfig(
645  reportingFrequency: number,
646  spRecordPerf: SpRecordPerf,
647  recordSetting: SpRecordSetting,
648  request: CreateSessionRequest
649): void {
650  if (!spRecordPerf!.startSamp) {
651    return;
652  }
653  let perfConfig = spRecordPerf!.getPerfConfig();
654  let recordArgs = '';
655  recordArgs = `${recordArgs}-f ${perfConfig?.frequency}`;
656  if (perfConfig?.process && !perfConfig?.process.includes('ALL') && perfConfig?.process.length > 0) {
657    let process = perfConfig.process;
658    if (process.indexOf(',') !== -1) {
659      let processIdOrName = process.split(',');
660      if (!isNaN(Number(processIdOrName[0]))) {
661        recordArgs = `${recordArgs} -p ${perfConfig?.process}`;
662      } else {
663        recordArgs = `${recordArgs} --app ${perfConfig?.process}`;
664      }
665    } else {
666      if (!isNaN(Number(process))) {
667        recordArgs = `${recordArgs} -p ${perfConfig?.process}`;
668      } else {
669        recordArgs = `${recordArgs} --app ${perfConfig?.process}`;
670      }
671    }
672  } else {
673    recordArgs = `${recordArgs} -a `;
674  }
675  recordArgs = initHiPerfConfig(perfConfig, recordArgs);
676  info('record config Args is: ', recordArgs);
677  let hiPerf: HiperfPluginConfig = {
678    isRoot: false,
679    outfileName: '/data/local/tmp/perf.data',
680    recordArgs: recordArgs,
681  };
682  if (SpApplication.isLongTrace) {
683    hiPerf.splitOutfileName = `${recordSetting!.longOutPath}hiprofiler_data_hiperf.htrace`;
684  }
685  request.pluginConfigs.push({
686    pluginName: 'hiperf-plugin',
687    sampleInterval: reportingFrequency * 1000,
688    configData: hiPerf,
689  });
690}
691
692export function createSystemConfig(
693  spFileSystem: SpFileSystem,
694  recordSetting: SpRecordSetting,
695  request: CreateSessionRequest
696): void {
697  if (!spFileSystem!.startRecord) {
698    return;
699  }
700  let systemConfig = spFileSystem!.getSystemConfig();
701  let recordArgs = 'hiebpf';
702  let recordEvent = [];
703  if (spFileSystem?.startFileSystem) {
704    recordEvent.push('fs');
705  }
706  if (spFileSystem?.startVirtualMemory) {
707    recordEvent.push('ptrace');
708  }
709  if (spFileSystem?.startIo) {
710    recordEvent.push('bio');
711  }
712  if (recordEvent.length > 0) {
713    recordArgs += ` --events ${recordEvent.toString()}`;
714  }
715  recordArgs += ` --duration ${recordSetting?.maxDur}`;
716  if (systemConfig?.process && !systemConfig?.process.includes('ALL') && systemConfig?.process.length > 0) {
717    recordArgs = `${recordArgs} --pids ${systemConfig?.process}`;
718  }
719  recordArgs += ` --max_stack_depth ${systemConfig?.unWindLevel}`;
720  let systemPluginConfig: HiebpfConfig = {
721    cmdLine: recordArgs,
722    outfileName: '/data/local/tmp/ebpf.data',
723  };
724  if (SpApplication.isLongTrace) {
725    systemPluginConfig.splitOutfileName = `${recordSetting?.longOutPath}hiprofiler_data_ebpf.htrace`;
726  }
727  request.pluginConfigs.push({
728    pluginName: 'hiebpf-plugin',
729    sampleInterval: 1000,
730    configData: systemPluginConfig,
731  });
732}
733
734export function createSdkConfig(spSdkConfig: SpSdkConfig, request: CreateSessionRequest): void {
735  if (spSdkConfig.startSamp && spSdkConfig.getPlugName() !== '') {
736    let gpuConfig = spSdkConfig!.getGpuConfig();
737    request.pluginConfigs.push({
738      pluginName: spSdkConfig!.getPlugName(),
739      sampleInterval: spSdkConfig!.getSampleInterval(),
740      configData: gpuConfig,
741    });
742  }
743  return;
744}
745
746export function createHiSystemEventPluginConfig(spHiSysEvent: SpHisysEvent, request: CreateSessionRequest): void {
747  if (!spHiSysEvent.startSamp) {
748    return;
749  }
750  request.pluginConfigs.push({
751    pluginName: 'hisysevent-plugin',
752    configData: {
753      msg: 'hisysevent-plugin',
754      subscribe_domain: spHiSysEvent.domain,
755      subscribe_event: spHiSysEvent.eventName,
756    },
757  });
758}
759
760export function createArkTsConfig(
761  spArkTs: SpArkTs,
762  recordSetting: SpRecordSetting,
763  request: CreateSessionRequest
764): void {
765  if (spArkTs.process !== '' && spArkTs.startSamp) {
766    let process = spArkTs!.process;
767    let re = /^[0-9]+.?[0-9]*/;
768    let pid = 0;
769    let processId = '';
770    if (process.indexOf('(') !== -1) {
771      processId = process.slice(process.lastIndexOf('(') + 1, process.lastIndexOf(')'));
772    } else {
773      processId = process;
774    }
775    if (re.test(processId)) {
776      pid = Number(processId);
777    }
778    let arkTSConfig: ArkTSConfig = {
779      pid: pid,
780      type: spArkTs.radioBoxType,
781      interval: spArkTs.intervalValue,
782      capture_numeric_value: spArkTs.grabNumeric,
783      track_allocations: spArkTs.grabAllocations,
784      enable_cpu_profiler: spArkTs.grabCpuProfiler,
785      cpu_profiler_interval: spArkTs.intervalCpuValue,
786    };
787    if (SpApplication.isLongTrace) {
788      arkTSConfig.splitOutfileName = `${recordSetting?.longOutPath}hiprofiler_data_arkts.htrace`;
789    }
790    request.pluginConfigs.push({
791      pluginName: 'arkts-plugin',
792      sampleInterval: 5000,
793      configData: arkTSConfig,
794    });
795  }
796  return;
797}
798
799export function createHiLogConfig(
800  reportingFrequency: number,
801  spHiLog: SpHilogRecord,
802  request: CreateSessionRequest
803): void {
804  if (!spHiLog.recordHilog) {
805    return;
806  }
807  let appProcess = spHiLog!.appProcess;
808  let re = /^[0-9]+.?[0-9]*/;
809  let pid = 0;
810  let processId = '';
811  if (appProcess.indexOf('(') !== -1) {
812    processId = appProcess.slice(appProcess.lastIndexOf('(') + 1, appProcess.lastIndexOf(')'));
813  } else {
814    processId = appProcess;
815  }
816  if (re.test(processId)) {
817    pid = Number(processId);
818  }
819  let hiLogConfig: HilogConfig = {
820    pid: pid,
821    logLevel: levelFromJSON(spHiLog!.appLogLevel),
822    needClear: true,
823  };
824  request.pluginConfigs.push({
825    pluginName: 'hilog-plugin',
826    sampleInterval: reportingFrequency * 1000,
827    configData: hiLogConfig,
828  });
829}
830
831export function createFFRTPluginConfig(
832  currentConfigPage: SpFFRTConfig,
833  selectVersion: string | null,
834  request: CreateSessionRequest
835): void {
836  if (currentConfigPage &&
837    (
838      currentConfigPage.processIds.length > 0 ||
839      currentConfigPage.restartProcessNames.length > 0 ||
840      currentConfigPage.startupProcessNames.length > 0
841    ) &&
842    currentConfigPage.startSamp) {
843    let config: FFRTConfig = {};
844    if (currentConfigPage.processIds.length > 0) {
845      config.pid = currentConfigPage.processIds;
846    }
847    if (currentConfigPage.startupProcessNames.length > 0) {
848      config.startupProcessName = currentConfigPage!.startupProcessNames;
849    }
850    if (currentConfigPage.restartProcessNames.length > 0) {
851      config.restartProcessName = currentConfigPage.restartProcessNames;
852    }
853    config.smbPages = currentConfigPage.smbPages;
854    config.flushInterval = currentConfigPage.flushInterval;
855    config.block = currentConfigPage.useBlock;
856    config.clockId = currentConfigPage!.clockType;
857    request.pluginConfigs.push({
858      pluginName: 'ffrt-profiler',
859      configData: config,
860    });
861  }
862}
863
864export function createTraceEvents(traceConfig: Array<string>): Array<string> {
865  let traceEvents = new Set<string>();
866  traceConfig.forEach((config) => {
867    switch (config) {
868      case 'Scheduling details':
869        schedulingEvents.forEach((eve: string) => {
870          traceEvents.add(eve);
871        });
872        break;
873      case 'CPU Frequency and idle states':
874        cpuFreqEvents.forEach((eve: string) => {
875          traceEvents.add(eve);
876        });
877        break;
878      case 'High frequency memory':
879        highFrequencyEvents.forEach((eve: string) => {
880          traceEvents.add(eve);
881        });
882        break;
883      case 'Advanced ftrace config':
884        advancedConfigEvents.forEach((eve: string) => {
885          traceEvents.add(eve);
886        });
887        break;
888      case 'Syscalls':
889        sysCallsEvents.forEach((eve: string) => {
890          traceEvents.add(eve);
891        });
892        break;
893      case 'Board voltages & frequency':
894        powerEvents.forEach((eve: string) => {
895          traceEvents.add(eve);
896        });
897        break;
898    }
899  });
900  let ftraceEventsArray: string[] = [];
901  info('traceEvents length is: ', traceEvents.size);
902  for (const ftraceEvent of traceEvents) {
903    ftraceEventsArray.push(ftraceEvent);
904  }
905  return ftraceEventsArray;
906}
907
908export function createXPowerConfig( 
909  spXPower: SpXPowerRecord,
910  request: CreateSessionRequest
911): void {
912  if (!spXPower.recordXPower) {
913    return;
914  }
915  let type = spXPower.getXpowerConfig();
916  let typeList: Array<string> = [];
917  typeList = type!.split(",");
918  let xPowerConfig = {
919    messageType: typeList
920  }
921  request.pluginConfigs.push({
922    pluginName: 'xpower-plugin',
923    sampleInterval: 1000,
924    is_protobuf_serialize: true,
925    configData: xPowerConfig,
926  });
927}
928
929let hasMonitorMemory = false;
930