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'; 17import '../../../base-ui/radiobox/LitRadioBox'; 18import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox'; 19import '../../../base-ui/slider/LitSlider'; 20import { LitSlider } from '../../../base-ui/slider/LitSlider'; 21import '../../../base-ui/popover/LitPopover'; 22import { info } from '../../../log/Log'; 23import { SpApplication } from '../../SpApplication'; 24import { NUM_200, NUM_30, NUM_3600, NUM_60, NUM_64 } from '../../bean/NumBean'; 25import { SpRecordSettingHtml } from './SpRecordSetting.html'; 26 27@element('record-setting') 28export class SpRecordSetting extends BaseElement { 29 private memoryBufferSlider: LitSlider | undefined; 30 private maxDurationSliders: LitSlider | undefined; 31 private radioBox: LitRadioBox | undefined; 32 private longTraceRadio: LitRadioBox | undefined; 33 private bufferNumber: HTMLElement | undefined; 34 private durationNumber: HTMLElement | undefined; 35 private outputPath: HTMLInputElement | undefined; 36 private lastMemoryValue: string | undefined; 37 private lastDurationValue: string | undefined; 38 private maxSizeInput: HTMLInputElement | undefined; 39 isRecordTemplate: boolean = false; 40 41 get longTraceSingleFileMaxSize(): number { 42 let maxFileSizeEl = this.shadowRoot?.querySelector<HTMLInputElement>('.max_size_result'); 43 if (maxFileSizeEl) { 44 return Number(maxFileSizeEl.value); 45 } 46 return NUM_200; 47 } 48 49 get recordMod(): boolean { 50 if (this.radioBox) { 51 return this.radioBox.checked; 52 } 53 return false; 54 } 55 56 get longOutPath(): string { 57 if (this.outputPath && this.outputPath.value !== '' && this.outputPath.value !== 'long_trace') { 58 return `/data/local/tmp/${this.outputPath.value}/`; 59 } 60 return '/data/local/tmp/long_trace/'; 61 } 62 63 get output(): string { 64 if (SpApplication.isLongTrace && !this.isRecordTemplate) { 65 if (this.outputPath && this.outputPath.value !== 'long_trace/' && this.outputPath.value !== '') { 66 return `/data/local/tmp/${this.outputPath.value}/hiprofiler_data.htrace`; 67 } 68 return '/data/local/tmp/long_trace/hiprofiler_data.htrace'; 69 } else { 70 if (this.outputPath && this.outputPath.value !== '') { 71 return `/data/local/tmp/${this.outputPath.value}`; 72 } 73 return '/data/local/tmp/hiprofiler_data.htrace'; 74 } 75 } 76 77 get bufferSize(): number { 78 if (this.bufferNumber?.hasAttribute('percent')) { 79 info('bufferSize is : ', this.bufferNumber!.getAttribute('percent')); 80 return Number(this.bufferNumber!.getAttribute('percent')); 81 } 82 return NUM_64; 83 } 84 85 get maxDur(): number { 86 if (this.durationNumber?.hasAttribute('percent')) { 87 info('maxDur is : ', this.durationNumber!.getAttribute('percent')); 88 return Number(this.durationNumber!.getAttribute('percent')); 89 } 90 return NUM_30; 91 } 92 93 resetValue(): void { 94 let bufferInput = this.shadowRoot?.querySelector('.memory_buffer_result') as HTMLInputElement; 95 let parentElement = this.memoryBufferSlider!.parentNode as Element; 96 if (bufferInput.style.color !== 'var(--dark-color1,#000000)' && this.lastMemoryValue) { 97 bufferInput.value = `${this.lastMemoryValue}`; 98 this.memoryBufferSlider!.percent = `${this.lastMemoryValue}`; 99 this.memoryBufferSlider!.sliderStyle = { 100 minRange: 4, 101 maxRange: 512, 102 defaultValue: `${this.lastMemoryValue}`, 103 resultUnit: 'MB', 104 stepSize: 2, 105 lineColor: 'var(--dark-color3,#46B1E3)', 106 buttonColor: '#999999', 107 }; 108 parentElement.setAttribute('percent', `${this.lastMemoryValue}`); 109 this.lastMemoryValue = `${this.lastMemoryValue}`; 110 bufferInput.style.color = 'var(--dark-color1,#000000)'; 111 } 112 113 let durationInput = this.shadowRoot?.querySelector('.max_duration_result') as HTMLInputElement; 114 let durationEl = this.maxDurationSliders!.parentNode as Element; 115 if (durationInput.style.color !== 'var(--dark-color1,#000000)' && this.lastDurationValue) { 116 durationInput.style.color = 'var(--dark-color1,#000000)'; 117 let durationList = this.lastDurationValue.split(':'); 118 let resultDuration = 119 Number(durationList[0]) * NUM_3600 + Number(durationList[1]) * NUM_60 + Number(durationList[2]); 120 durationInput.value = this.lastDurationValue; 121 this.maxDurationSliders!.sliderStyle = { 122 minRange: 10, 123 maxRange: 3600, 124 defaultValue: this.lastDurationValue!, 125 resultUnit: 'h:m:s', 126 stepSize: 1, 127 lineColor: 'var(--dark-color4,#61CFBE)', 128 buttonColor: '#999999', 129 }; 130 durationEl.setAttribute('percent', resultDuration.toString()); 131 } 132 } 133 134 initElements(): void { 135 this.bufferNumber = this.shadowRoot?.querySelector('.buffer-size') as HTMLElement; 136 this.durationNumber = this.shadowRoot?.querySelector('.max-duration') as HTMLElement; 137 let inputs = this.shadowRoot?.querySelectorAll('input'); 138 inputs!.forEach((item) => { 139 item.addEventListener('keydown', (ev) => { 140 // @ts-ignore 141 if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') { 142 ev.preventDefault(); 143 } 144 }); 145 }); 146 this.shadowRoot?.querySelectorAll<HTMLButtonElement>('.MenuButton').forEach((button) => { 147 button!.addEventListener('mouseenter', () => { 148 button.style.backgroundColor = '#EFEFEF'; 149 }); 150 button!.addEventListener('mouseout', () => { 151 button.style.backgroundColor = '#E4E3E9'; 152 }); 153 }); 154 this.radioBox = this.shadowRoot?.querySelector('#litradio') as LitRadioBox; 155 this.addLongTraceConfig(); 156 this.initLitSlider(); 157 } 158 159 private getLongTraceSlideHTML(): string { 160 return `<div class="max-single-file-size"> 161 <div class="record-title"> 162 <span class="record-mode" >Single file max size</span> 163 <span class="record-prompt"> (single file size after cutting is 200MB - 300MB) </span> 164 </div> 165 <lit-slider id="max-size" defaultColor="var(--dark-color4,#86C5E3)" open dir="right"> 166 </lit-slider> 167 <div class='resultValue'> 168 <input class="max_size_result" type="text" value = '200' 169 oninput="if(this.value > 300){this.value = '300'} 170 if (this.value < 200) { 171 this.parentElement.style.border = '1px solid red' 172 } else { 173 this.parentElement.style.border = '1px solid #ccc' 174 } 175 if (this.value > 0 && this.value.toString().startsWith('0')){ 176 this.value = Number(this.value) 177 }" > 178 <span style="text-align: center; margin: 8px 8px 8px 0"> MB </span> 179 </div> 180 </div>`; 181 } 182 183 private addLongTraceConfig(): void { 184 this.longTraceRadio = this.shadowRoot?.querySelector('#longTraceRadio') as LitRadioBox; 185 this.outputPath = this.shadowRoot?.querySelector<HTMLInputElement>('#trace_path') as HTMLInputElement; 186 let rootEl = this.shadowRoot?.querySelector('.root') as HTMLDivElement; 187 let longTraceMaxSlide = document.createElement('div'); 188 longTraceMaxSlide.innerHTML = this.getLongTraceSlideHTML(); 189 let maxSingleFileEl = longTraceMaxSlide.querySelector<HTMLDivElement>('.max-single-file-size'); 190 let maxSizeSliders = longTraceMaxSlide.querySelector('#max-size') as LitSlider; 191 this.maxSizeInput = longTraceMaxSlide.querySelector('.max_size_result') as HTMLInputElement; 192 this.maxSizeInput.onkeydown = (ev): void => { 193 // @ts-ignore 194 if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') { 195 ev.preventDefault(); 196 } 197 }; 198 let maxSizeParentElement = maxSizeSliders.parentNode as Element; 199 maxSizeSliders.sliderStyle = { 200 minRange: 200, 201 maxRange: 300, 202 defaultValue: '200', 203 resultUnit: 'MB', 204 stepSize: 2, 205 lineColor: 'var(--dark-color3,#46B1E3)', 206 buttonColor: '#999999', 207 }; 208 maxSizeSliders.addEventListener('input', () => { 209 if (maxSingleFileEl?.hasAttribute('percent')) { 210 this.maxSizeInput!.value = `${maxSingleFileEl?.getAttribute('percent')}`; 211 } else { 212 this.maxSizeInput!.value = maxSizeSliders.sliderStyle.defaultValue; 213 } 214 }); 215 this.maxSizeInput.value = maxSizeSliders.sliderStyle.defaultValue; 216 maxSizeParentElement.setAttribute('percent', '50'); 217 this.maxSizeInput.style.color = 'var(--dark-color1,#000000)'; 218 this.maxSizeInput.addEventListener('input', () => { 219 this.maxSizeInputHandler(maxSizeSliders, maxSizeParentElement); 220 }); 221 this.radioBox!.addEventListener('click', () => { 222 this.normalModelRadioHandler(rootEl, longTraceMaxSlide); 223 }); 224 this.longTraceRadio.addEventListener('click', () => { 225 this.longTraceModelRadioHandler(rootEl, longTraceMaxSlide); 226 }); 227 } 228 229 private normalModelRadioHandler(rootEl: HTMLDivElement, longTraceMaxSlide: HTMLDivElement): void { 230 SpApplication.isLongTrace = false; 231 if (rootEl.lastChild === longTraceMaxSlide) { 232 rootEl.removeChild(longTraceMaxSlide); 233 } 234 this.outputPath!.value = 'hiprofiler_data.htrace'; 235 } 236 237 private longTraceModelRadioHandler(rootEl: HTMLDivElement, longTraceMaxSlide: HTMLDivElement): void { 238 SpApplication.isLongTrace = true; 239 rootEl.appendChild(longTraceMaxSlide); 240 this.outputPath!.value = 'long_trace'; 241 } 242 243 private maxSizeInputHandler(maxSizeSliders: LitSlider, maxSizeParentElement: Element): void { 244 maxSizeSliders!.percent = this.maxSizeInput!.value; 245 let htmlInputElement = maxSizeSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 246 htmlInputElement.value = this.maxSizeInput!.value; 247 maxSizeSliders!.sliderStyle = { 248 minRange: 200, 249 maxRange: 300, 250 defaultValue: this.maxSizeInput!.value, 251 resultUnit: 'MB', 252 stepSize: 2, 253 lineColor: 'var(--dark-color3,#46B1E3)', 254 buttonColor: '#999999', 255 }; 256 maxSizeParentElement.setAttribute('percent', this.maxSizeInput!.value); 257 } 258 259 initLitSlider(): void { 260 this.memoryBufferSlider = this.shadowRoot?.querySelector<LitSlider>('#memory-buffer') as LitSlider; 261 this.memoryBufferSlider.sliderStyle = { 262 minRange: 4, 263 maxRange: 512, 264 defaultValue: '64', 265 resultUnit: 'MB', 266 stepSize: 2, 267 lineColor: 'var(--dark-color3,#46B1E3)', 268 buttonColor: '#999999', 269 }; 270 this.lastMemoryValue = '64'; 271 this.initMemoryBufferEl(); 272 this.maxDurationSliders = this.shadowRoot?.querySelector<LitSlider>('#max-duration') as LitSlider; 273 this.maxDurationSliders.sliderStyle = { 274 minRange: 10, 275 maxRange: 3600, 276 defaultValue: '00:00:30', 277 resultUnit: 'h:m:s', 278 stepSize: 1, 279 lineColor: 'var(--dark-color4,#61CFBE)', 280 buttonColor: '#999999', 281 }; 282 this.lastDurationValue = '00:00:30'; 283 let durationParentElement = this.maxDurationSliders!.parentNode as Element; 284 let durationInput = this.shadowRoot?.querySelector('.max_duration_result') as HTMLInputElement; 285 durationInput.value = this.maxDurationSliders.sliderStyle.defaultValue; 286 this.maxDurationSliders.addEventListener('input', () => { 287 durationInput.value = this.maxDurationSliders!.formatSeconds(this.maxDur.toString()); 288 }); 289 durationInput.style.color = 'var(--dark-color1,#000000)'; 290 durationInput.addEventListener('input', () => { 291 this.maxDurationInputHandler(durationInput, durationParentElement); 292 }); 293 let maxDurationInput = this.maxDurationSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 294 maxDurationInput.addEventListener('input', () => { 295 durationInput.style.color = 'var(--dark-color1,#000000)'; 296 durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 297 durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 298 }); 299 } 300 301 private initMemoryBufferEl(): void { 302 let parentElement = this.memoryBufferSlider!.parentNode as Element; 303 let bufferInput = this.shadowRoot?.querySelector('.memory_buffer_result') as HTMLInputElement; 304 bufferInput.value = this.memoryBufferSlider!.sliderStyle.defaultValue; 305 this.memoryBufferSlider!.addEventListener('input', () => { 306 bufferInput.value = this.bufferSize.toString(); 307 }); 308 parentElement.setAttribute('percent', '64'); 309 bufferInput.style.color = 'var(--dark-color1,#000000)'; 310 bufferInput.addEventListener('input', () => { 311 this.memoryBufferInputHandler(bufferInput, parentElement); 312 }); 313 let memoryBufferInput = this.memoryBufferSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 314 memoryBufferInput.addEventListener('input', () => { 315 bufferInput.style.color = 'var(--dark-color1,#000000)'; 316 bufferInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 317 bufferInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 318 }); 319 } 320 321 private maxDurationInputHandler(durationInput: HTMLInputElement, durationParentElement: Element): void { 322 if (this.durationNumber!.hasAttribute('percent')) { 323 this.durationNumber!.removeAttribute('percent'); 324 } 325 durationInput.style.color = 'var(--dark-color1,#000000)'; 326 durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 327 durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 328 let regExpMatchArray = durationInput.value.trim(); 329 if (regExpMatchArray === '') { 330 durationInput.style.color = 'red'; 331 durationParentElement.setAttribute('percent', '30'); 332 return; 333 } 334 let regExpMatch = durationInput.value.trim().match('^\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}$'); 335 if (regExpMatch) { 336 let durationList = regExpMatchArray.split(':'); 337 let resultDuration = 338 Number(durationList[0]) * NUM_3600 + Number(durationList[1]) * NUM_60 + Number(durationList[2]); 339 if ( 340 Number(durationList[0]) > NUM_60 || 341 Number(durationList[1]) > NUM_60 || 342 Number(durationList[2]) > NUM_60 || 343 resultDuration > this.maxDurationSliders!.sliderStyle.maxRange || 344 resultDuration < this.maxDurationSliders!.sliderStyle.minRange 345 ) { 346 durationInput.style.color = 'red'; 347 durationParentElement.setAttribute('percent', '30'); 348 } else { 349 durationInput.style.color = 'var(--dark-color1,#000000)'; 350 durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 351 durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 352 let htmlInputElement = this.maxDurationSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 353 htmlInputElement.value = `${resultDuration}`; 354 this.maxDurationSliders!.sliderStyle = { 355 minRange: 10, 356 maxRange: 3600, 357 defaultValue: `${Number(durationList[0])}:${Number(durationList[1])}:${Number(durationList[2])}`, 358 resultUnit: 'h:m:s', 359 stepSize: 1, 360 lineColor: 'var(--dark-color4,#61CFBE)', 361 buttonColor: '#999999', 362 }; 363 durationParentElement.setAttribute('percent', resultDuration.toString()); 364 this.lastDurationValue = regExpMatchArray; 365 } 366 } else { 367 durationInput.style.color = 'red'; 368 durationParentElement.setAttribute('percent', '30'); 369 } 370 } 371 372 private memoryBufferInputHandler(bufferInput: HTMLInputElement, parentElement: Element): void { 373 if (this.bufferNumber!.hasAttribute('percent')) { 374 this.bufferNumber!.removeAttribute('percent'); 375 } 376 bufferInput.style.color = 'var(--dark-color1,#000000)'; 377 bufferInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 378 bufferInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 379 if (bufferInput.value.trim() === '') { 380 bufferInput.style.color = 'red'; 381 parentElement.setAttribute('percent', '64'); 382 return; 383 } 384 let memorySize = Number(bufferInput.value); 385 if ( 386 !memorySize || 387 memorySize < this.memoryBufferSlider!.sliderStyle.minRange || 388 memorySize > this.memoryBufferSlider!.sliderStyle.maxRange 389 ) { 390 bufferInput.style.color = 'red'; 391 parentElement.setAttribute('percent', '64'); 392 } else { 393 this.memoryBufferSlider!.percent = bufferInput.value; 394 let htmlInputElement = this.memoryBufferSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 395 htmlInputElement.value = bufferInput.value; 396 this.memoryBufferSlider!.sliderStyle = { 397 minRange: 4, 398 maxRange: 512, 399 defaultValue: bufferInput.value, 400 resultUnit: 'MB', 401 stepSize: 2, 402 lineColor: 'var(--dark-color3,#46B1E3)', 403 buttonColor: '#999999', 404 }; 405 parentElement.setAttribute('percent', bufferInput.value); 406 this.lastMemoryValue = bufferInput.value; 407 } 408 } 409 410 initHtml(): string { 411 return SpRecordSettingHtml; 412 } 413} 414