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