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/radiobox/LitRadioBox.js'; 18import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox.js'; 19import '../../../base-ui/slider/LitSlider.js'; 20import { LitSlider } from '../../../base-ui/slider/LitSlider.js'; 21import '../../../base-ui/popover/LitPopover.js'; 22import { info } from '../../../log/Log.js'; 23 24@element('record-setting') 25export class SpRecordSetting extends BaseElement { 26 private memoryBufferSlider: LitSlider | undefined; 27 private maxDurationSliders: LitSlider | undefined; 28 private radioBox: LitRadioBox | undefined; 29 private bufferNumber: HTMLElement | undefined; 30 private durationNumber: HTMLElement | undefined; 31 private outputPath: HTMLInputElement | undefined; 32 private lastMemoryValue: string | undefined; 33 private lastDurationValue: string | undefined; 34 35 get recordMod(): boolean { 36 if (this.radioBox) { 37 return this.radioBox.checked; 38 } 39 return false; 40 } 41 42 get output(): string { 43 if (this.outputPath && this.outputPath.value != '') { 44 return '/data/local/tmp/' + this.outputPath.value; 45 } 46 return '/data/local/tmp/hiprofiler_data.htrace'; 47 } 48 49 get bufferSize(): number { 50 if (this.bufferNumber?.hasAttribute('percent')) { 51 info('bufferSize is : ', this.bufferNumber!.getAttribute('percent')); 52 return Number(this.bufferNumber!.getAttribute('percent')); 53 } 54 return 64; 55 } 56 57 get maxDur(): number { 58 if (this.durationNumber?.hasAttribute('percent')) { 59 info('maxDur is : ', this.durationNumber!.getAttribute('percent')); 60 return Number(this.durationNumber!.getAttribute('percent')); 61 } 62 return 30; 63 } 64 65 resetValue(): void { 66 let bufferInput = this.shadowRoot?.querySelector('.memory_buffer_result') as HTMLInputElement; 67 let parentElement = this.memoryBufferSlider!.parentNode as Element; 68 if (bufferInput.style.color != 'var(--dark-color1,#000000)' && this.lastMemoryValue) { 69 bufferInput.value = this.lastMemoryValue + ''; 70 this.memoryBufferSlider!.percent = this.lastMemoryValue + ''; 71 this.memoryBufferSlider!.sliderStyle = { 72 minRange: 4, 73 maxRange: 512, 74 defaultValue: this.lastMemoryValue + '', 75 resultUnit: 'MB', 76 stepSize: 2, 77 lineColor: 'var(--dark-color3,#46B1E3)', 78 buttonColor: '#999999', 79 }; 80 parentElement.setAttribute('percent', this.lastMemoryValue + ''); 81 this.lastMemoryValue = this.lastMemoryValue + ''; 82 bufferInput.style.color = 'var(--dark-color1,#000000)'; 83 } 84 85 let durationInput = this.shadowRoot?.querySelector('.max_duration_result') as HTMLInputElement; 86 let durationEl = this.maxDurationSliders!.parentNode as Element; 87 if (durationInput.style.color != 'var(--dark-color1,#000000)' && this.lastDurationValue) { 88 durationInput.style.color = 'var(--dark-color1,#000000)'; 89 let durationList = this.lastDurationValue.split(':'); 90 let resultDuration = Number(durationList[0]) * 3600 + Number(durationList[1]) * 60 + Number(durationList[2]); 91 92 durationInput.value = this.lastDurationValue; 93 this.maxDurationSliders!.sliderStyle = { 94 minRange: 10, 95 maxRange: 3600, 96 defaultValue: this.lastDurationValue!, 97 resultUnit: 'h:m:s', 98 stepSize: 1, 99 lineColor: 'var(--dark-color4,#61CFBE)', 100 buttonColor: '#999999', 101 }; 102 durationEl.setAttribute('percent', resultDuration.toString()); 103 } 104 } 105 106 initElements(): void { 107 this.bufferNumber = this.shadowRoot?.querySelector('.buffer-size') as HTMLElement; 108 this.durationNumber = this.shadowRoot?.querySelector('.max-duration') as HTMLElement; 109 let bu = this.shadowRoot?.querySelector('.record') as HTMLDivElement; 110 this.shadowRoot?.querySelectorAll<HTMLButtonElement>('.MenuButton').forEach((button) => { 111 button!.addEventListener('mouseenter', (e) => { 112 button.style.backgroundColor = '#EFEFEF'; 113 }); 114 115 button!.addEventListener('mouseout', (e) => { 116 button.style.backgroundColor = '#E4E3E9'; 117 }); 118 }); 119 120 this.radioBox = this.shadowRoot?.querySelector('#litradio') as LitRadioBox; 121 this.outputPath = this.shadowRoot?.querySelector<HTMLInputElement>('#trace_path') as HTMLInputElement; 122 123 this.initLitSlider(); 124 } 125 126 initLitSlider() { 127 this.memoryBufferSlider = this.shadowRoot?.querySelector<LitSlider>('#memory-buffer') as LitSlider; 128 this.memoryBufferSlider.sliderStyle = { 129 minRange: 4, 130 maxRange: 512, 131 defaultValue: '64', 132 resultUnit: 'MB', 133 stepSize: 2, 134 lineColor: 'var(--dark-color3,#46B1E3)', 135 buttonColor: '#999999', 136 }; 137 this.lastMemoryValue = '64'; 138 let parentElement = this.memoryBufferSlider!.parentNode as Element; 139 let bufferInput = this.shadowRoot?.querySelector('.memory_buffer_result') as HTMLInputElement; 140 bufferInput.value = this.memoryBufferSlider.sliderStyle.defaultValue; 141 this.memoryBufferSlider.addEventListener('input', (evt) => { 142 bufferInput.value = this.bufferSize.toString(); 143 }); 144 parentElement.setAttribute('percent', '64'); 145 bufferInput.style.color = 'var(--dark-color1,#000000)'; 146 bufferInput.addEventListener('input', (ev) => { 147 if (this.bufferNumber!.hasAttribute('percent')) { 148 this.bufferNumber!.removeAttribute('percent'); 149 } 150 bufferInput.style.color = 'var(--dark-color1,#000000)'; 151 bufferInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 152 bufferInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 153 if (bufferInput.value.trim() == '') { 154 bufferInput.style.color = 'red'; 155 parentElement.setAttribute('percent', '64'); 156 return; 157 } 158 let memorySize = Number(bufferInput.value); 159 if ( 160 !memorySize || 161 memorySize < this.memoryBufferSlider!.sliderStyle.minRange || 162 memorySize > this.memoryBufferSlider!.sliderStyle.maxRange 163 ) { 164 bufferInput.style.color = 'red'; 165 parentElement.setAttribute('percent', '64'); 166 } else { 167 this.memoryBufferSlider!.percent = bufferInput.value; 168 let htmlInputElement = this.memoryBufferSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 169 htmlInputElement.value = bufferInput.value; 170 this.memoryBufferSlider!.sliderStyle = { 171 minRange: 4, 172 maxRange: 512, 173 defaultValue: bufferInput.value, 174 resultUnit: 'MB', 175 stepSize: 2, 176 lineColor: 'var(--dark-color3,#46B1E3)', 177 buttonColor: '#999999', 178 }; 179 parentElement.setAttribute('percent', bufferInput.value); 180 this.lastMemoryValue = bufferInput.value; 181 } 182 }); 183 184 let memoryBufferInput = this.memoryBufferSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 185 186 memoryBufferInput.addEventListener('input', (ev) => { 187 bufferInput.style.color = 'var(--dark-color1,#000000)'; 188 bufferInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 189 bufferInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 190 }); 191 192 this.maxDurationSliders = this.shadowRoot?.querySelector<LitSlider>('#max-duration') as LitSlider; 193 this.maxDurationSliders.sliderStyle = { 194 minRange: 10, 195 maxRange: 3600, 196 defaultValue: '00:00:30', 197 resultUnit: 'h:m:s', 198 stepSize: 1, 199 lineColor: 'var(--dark-color4,#61CFBE)', 200 buttonColor: '#999999', 201 }; 202 this.lastDurationValue = '00:00:30'; 203 let durationParentElement = this.maxDurationSliders!.parentNode as Element; 204 let durationInput = this.shadowRoot?.querySelector('.max_duration_result') as HTMLInputElement; 205 durationInput.value = this.maxDurationSliders.sliderStyle.defaultValue; 206 this.maxDurationSliders.addEventListener('input', (evt) => { 207 durationInput.value = this.maxDurationSliders!.formatSeconds(this.maxDur.toString()); 208 }); 209 210 durationInput.style.color = 'var(--dark-color1,#000000)'; 211 durationInput.addEventListener('input', (ev) => { 212 if (this.durationNumber!.hasAttribute('percent')) { 213 this.durationNumber!.removeAttribute('percent'); 214 } 215 durationInput.style.color = 'var(--dark-color1,#000000)'; 216 durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 217 durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 218 let regExpMatchArray = durationInput.value.trim(); 219 if (regExpMatchArray == '') { 220 durationInput.style.color = 'red'; 221 durationParentElement.setAttribute('percent', '30'); 222 return; 223 } 224 let regExpMatch = durationInput.value.trim().match(`^\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}$`); 225 if (regExpMatch) { 226 let durationList = regExpMatchArray.split(':'); 227 let resultDuration = Number(durationList[0]) * 3600 + Number(durationList[1]) * 60 + Number(durationList[2]); 228 if ( 229 Number(durationList[0]) > 60 || 230 Number(durationList[1]) > 60 || 231 Number(durationList[2]) > 60 || 232 resultDuration > this.maxDurationSliders!.sliderStyle.maxRange || 233 resultDuration < this.maxDurationSliders!.sliderStyle.minRange 234 ) { 235 durationInput.style.color = 'red'; 236 durationParentElement.setAttribute('percent', '30'); 237 } else { 238 durationInput.style.color = 'var(--dark-color1,#000000)'; 239 durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 240 durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 241 let htmlInputElement = this.maxDurationSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 242 htmlInputElement.value = resultDuration + ''; 243 this.maxDurationSliders!.sliderStyle = { 244 minRange: 10, 245 maxRange: 3600, 246 defaultValue: Number(durationList[0]) + ':' + Number(durationList[1]) + ':' + Number(durationList[2]), 247 resultUnit: 'h:m:s', 248 stepSize: 1, 249 lineColor: 'var(--dark-color4,#61CFBE)', 250 buttonColor: '#999999', 251 }; 252 durationParentElement.setAttribute('percent', resultDuration.toString()); 253 this.lastDurationValue = regExpMatchArray; 254 } 255 } else { 256 durationInput.style.color = 'red'; 257 durationParentElement.setAttribute('percent', '30'); 258 } 259 }); 260 261 let maxDurationInput = this.maxDurationSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 262 maxDurationInput.addEventListener('input', (ev) => { 263 durationInput.style.color = 'var(--dark-color1,#000000)'; 264 durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 265 durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 266 }); 267 } 268 269 initHtml(): string { 270 return ` 271 <style> 272 .root { 273 padding-top: 45px; 274 padding-left: 41px; 275 background: var(--dark-background3,#FFFFFF); 276 font-size:16px; 277 border-radius: 0px 16px 16px 0px; 278 overflow-y: auto; 279 display: grid; 280 grid-template-columns: repeat(1, 1fr); 281 grid-template-rows: min-content min-content min-content; 282 grid-gap: 50px; 283 } 284 :host{ 285 display: block; 286 border-radius: 0px 16px 16px 0px; 287 background: background: var(--dark-background3,#FFFFFF); 288 position: relative; 289 width: 100%; 290 height: 100%; 291 } 292 .record-mode{ 293 font-family: Helvetica-Bold; 294 font-size: 16px; 295 color: var(--dark-color1,#000000); 296 line-height: 28px; 297 font-weight: 700; 298 margin-bottom: 16px; 299 grid-column: span 1; 300 } 301 .record{ 302 display:flex; 303 flex-direction: column; 304 } 305 306 .output{ 307 display:grid; 308 } 309 310 .trace_file_span { 311 width: 20%; 312 height: 1em; 313 margin: 0; 314 } 315 316 #trace_path { 317 background-color: var(--dark-background5,#FFFFFF) 318 font-family: Helvetica-Bold; 319 color: var(--dark-color1,#8f8c8c); 320 margin: 0; 321 width: 25%; 322 height: 25px; 323 border-radius: 8px; 324 outline: none; 325 border: 1px solid #ccc; 326 } 327 .buffer-size{ 328 height: min-content; 329 display: grid; 330 grid-template-rows: 1fr; 331 grid-template-columns: 1fr min-content; 332 } 333 334 .max-duration{ 335 height: min-content; 336 display: grid; 337 grid-template-rows: 1fr 1fr; 338 grid-template-columns: 1fr 1fr min-content; 339 } 340 341 #litradio{ 342 opacity: 0.9; 343 font-family: Helvetica; 344 font-size: 14px; 345 color: var(--dark-color1,#000000); 346 text-align: left; 347 line-height: 16px; 348 font-weight: 400; 349 } 350 351 button{ 352 height: 25px; 353 width: 100%; 354 border: 0; 355 text-align: left; 356 padding-left: 20px; 357 margin-top: 10px; 358 background-color: #E4E3E9; 359 } 360 361 .line{ 362 width: 100%; 363 height: 1px; 364 overflow: hidden; 365 border-top: 1px solid #C5C7CF; 366 background: #E4E3E9; 367 margin-top: 4px; 368 display: inline-block; 369 vertical-align: middle; 370 } 371 372 .max_duration_result, .memory_buffer_result{ 373 background-color: var(--dark-background5,#F2F2F2); 374 color:var(--dark-color,#6a6f77); 375 border: none; 376 -webkit-appearance:none; 377 outline:0; 378 font-size:14px; 379 text-align: center; 380 width: 90px; 381 margin: 5px 0 5px 5px; 382 } 383 384 .resultValue, .resultSize{ 385 -webkit-appearance:none; 386 color:var(--dark-color,#6a6f77); 387 border-radius:20px; 388 margin: 0 30px 0 0; 389 background-color: var(--dark-background5,#F2F2F2); 390 display: grid; 391 grid-template-rows: 1fr; 392 grid-template-columns: min-content min-content; 393 width: 150px; 394 height: 40px; 395 outline:0; 396 border:1px solid var(--dark-border,#c8cccf); 397 } 398 399 #memory-buffer, #max-duration { 400 margin: 0 8px; 401 grid-column: span 2; 402 } 403 404 .record-title{ 405 margin-bottom: 16px; 406 grid-column: span 3; 407 } 408 409 .record-prompt{ 410 opacity: 0.6; 411 font-family: Helvetica; 412 font-size: 14px; 413 text-align: center; 414 line-height: 35px; 415 font-weight: 400; 416 } 417 418 </style> 419 <div class="root"> 420 <div class="record"> 421 <span class="record-mode">Record mode</span> 422 <lit-radio name="Stop when full" dis="round" id="litradio" checked>Stop when full</lit-radio> 423 </div> 424 <div class="output"> 425 <span class="record-mode">output file path</span> 426 <div> 427 <span class="trace_file_span">/data/local/tmp/</span> 428 <input id="trace_path" type="text" value='hiprofiler_data.htrace'onkeydown="this.value.length >= 100 ? this.value = this.value.substring(0,99): 0" oninput="this.value= this.value.replace('__','_')" onkeyup="this.value=this.value.replace(/[^\\w\\.]/g,'')"> 429 </div> 430 </div> 431 <div class="buffer-size"> 432 <div class="record-title"> 433 <span class="record-mode">In-memory buffer size</span> 434 <span class="record-prompt"> (max memory buffer size is 512 MB) </span> 435 </div> 436 <lit-slider id="memory-buffer" defaultColor="var(--dark-color3,#46B1E3)" open dir="right"> 437 </lit-slider> 438 <div class='resultSize'> 439 <input class="memory_buffer_result" type="text" value='64' onkeyup="this.value=this.value.replace(/\\D/g,'')"> 440 <span style="text-align: center; margin: 8px"> MB </span> 441 </div> 442 </div> 443 <div class="max-duration"> 444 <div class="record-title"> 445 <span class="record-mode" >Max duration</span> 446 <span class="record-prompt"> (max duration value is 01:00:00) </span> 447 </div> 448 <lit-slider id="max-duration" defaultColor="var(--dark-color4,#61CFBE)" open dir="right"> 449 </lit-slider> 450 <div class='resultValue'> 451 <input class="max_duration_result" type="text" value = '00:00:30' > 452 <span style="text-align: center; margin: 8px 8px 8px 0"> h:m:s </span> 453 </div> 454 455 </div> 456 </div> 457 `; 458 } 459} 460