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