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 { log } from '../../../log/Log'; 18import { SpRecordTrace } from '../SpRecordTrace'; 19import { Cmd } from '../../../command/Cmd'; 20import LitSwitch from '../../../base-ui/switch/lit-switch'; 21import { LitSlider } from '../../../base-ui/slider/LitSlider'; 22import { LitSelectV } from '../../../base-ui/select/LitSelectV'; 23import { SpAllocationHtml } from './SpAllocation.html'; 24import { 25 NUM_16384, 26 NUM_1800, 27 NUM_30, 28 NUM_300, 29 NUM_3600, 30 NUM_450, 31 NUM_60, 32 NUM_600 33} from '../../bean/NumBean'; 34 35@element('sp-allocations') 36export class SpAllocations extends BaseElement { 37 private processId: LitSelectV | null | undefined; 38 private unwindEL: HTMLInputElement | null | undefined; 39 private shareMemory: HTMLInputElement | null | undefined; 40 private shareMemoryUnit: HTMLSelectElement | null | undefined; 41 private filterMemory: HTMLInputElement | null | undefined; 42 private intervalResultInput: HTMLInputElement | null | undefined; 43 private fpUnWind: LitSwitch | null | undefined; 44 private statisticsSlider: LitSlider | null | undefined; 45 private recordAccurately: LitSwitch | null | undefined; 46 private offlineSymbol: LitSwitch | null | undefined; 47 private startupMode: LitSwitch | null | undefined; 48 private responseLibMode: LitSwitch | null | undefined; 49 private recordStatisticsResult: HTMLDivElement | null | undefined; 50 private sampleInterval: HTMLInputElement | null | undefined; 51 52 private filterSize: HTMLInputElement | null | undefined; 53 54 set startSamp(allocationStart: boolean) { 55 if (allocationStart) { 56 this.setAttribute('startSamp', ''); 57 } else { 58 this.removeAttribute('startSamp'); 59 } 60 } 61 62 get startSamp(): boolean { 63 return this.hasAttribute('startSamp'); 64 } 65 66 get appProcess(): string { 67 return this.processId!.value || ''; 68 } 69 70 get unwind(): number { 71 log(`unwind value is :${ this.unwindEL!.value}`); 72 return Number(this.unwindEL!.value); 73 } 74 75 get shared(): number { 76 let value = this.shareMemory?.value || ''; 77 log(`shareMemory value is :${ value}`); 78 if (value !== '') { 79 return Number(this.shareMemory?.value) || NUM_16384; 80 } 81 return NUM_16384; 82 } 83 84 get filter(): number { 85 let value = this.filterMemory?.value || ''; 86 log(`filter value is :${ value}`); 87 if (value !== '') { 88 return Number(value); 89 } 90 return 0; 91 } 92 93 get fp_unwind(): boolean { 94 let value = this.fpUnWind?.checked; 95 if (value !== undefined) { 96 return value; 97 } 98 return true; 99 } 100 101 get record_accurately(): boolean { 102 let value = this.recordAccurately?.checked; 103 if (value !== undefined) { 104 return value; 105 } 106 return true; 107 } 108 109 get offline_symbolization(): boolean { 110 let value = this.offlineSymbol?.checked; 111 if (value !== undefined) { 112 return value; 113 } 114 return true; 115 } 116 117 get record_statistics(): boolean { 118 if (this.recordStatisticsResult?.hasAttribute('percent')) { 119 let value = Number(this.recordStatisticsResult?.getAttribute('percent')); 120 return value > 0; 121 } 122 return true; 123 } 124 125 get statistics_interval(): number { 126 if (this.recordStatisticsResult?.hasAttribute('percentValue')) { 127 return Number(this.recordStatisticsResult?.getAttribute('percentValue')); 128 } 129 return 10; 130 } 131 132 get response_lib_mode(): boolean { 133 let value = this.responseLibMode?.checked; 134 if (value !== undefined) { 135 return value; 136 } 137 return false; 138 } 139 140 get startup_mode(): boolean { 141 let value = this.startupMode?.checked; 142 if (value !== undefined) { 143 return value; 144 } 145 return false; 146 } 147 148 set startup_mode(value: boolean) { 149 if (this.startupMode) { 150 this.startupMode.checked = value; 151 } 152 } 153 154 get expandPids(): number[] { 155 let allPidList: number[] = []; 156 if (this.processId?.value.length > 0) { 157 let result = this.processId?.value.match(/\((.+?)\)/g); 158 if (result) { 159 for (let index = 0; index < result.length; index++) { 160 let item = result[index]; 161 let currentPid = item!.replace('(', '').replace(')', ''); 162 allPidList.push(Number(currentPid)); 163 } 164 } 165 } 166 return allPidList; 167 } 168 169 get sample_interval(): number { 170 return Number(this.sampleInterval!.value); 171 } 172 173 connectedCallback(): void { 174 this.unwindEL?.addEventListener('keydown', this.handleInputChange); 175 this.shareMemory?.addEventListener('keydown', this.handleInputChange); 176 this.shareMemoryUnit?.addEventListener('keydown', this.handleInputChange); 177 this.filterMemory?.addEventListener('keydown', this.handleInputChange); 178 this.intervalResultInput?.addEventListener('keydown', this.handleInputChange); 179 this.filterSize?.addEventListener('keydown', this.handleInputChange); 180 this.statisticsSlider?.addEventListener('input', this.statisticsSliderInputHandler); 181 this.intervalResultInput?.addEventListener('input', this.intervalResultInputHandler); 182 this.intervalResultInput?.addEventListener('focusout', this.intervalResultFocusOutHandler); 183 this.statisticsSlider?.shadowRoot?.querySelector<HTMLElement>('#slider')!. 184 addEventListener('mouseup', this.statisticsSliderMouseupHandler); 185 this.startupMode?.addEventListener('change',this.startupModeChangeHandler); 186 } 187 188 disconnectedCallback(): void { 189 this.unwindEL?.removeEventListener('keydown', this.handleInputChange); 190 this.shareMemory?.removeEventListener('keydown', this.handleInputChange); 191 this.shareMemoryUnit?.removeEventListener('keydown', this.handleInputChange); 192 this.filterMemory?.removeEventListener('keydown', this.handleInputChange); 193 this.intervalResultInput?.removeEventListener('keydown', this.handleInputChange); 194 this.filterSize?.removeEventListener('keydown', this.handleInputChange); 195 this.statisticsSlider?.removeEventListener('input', this.statisticsSliderInputHandler); 196 this.intervalResultInput?.removeEventListener('input', this.intervalResultInputHandler); 197 this.intervalResultInput?.removeEventListener('focusout', this.intervalResultFocusOutHandler); 198 this.statisticsSlider?.shadowRoot?.querySelector<HTMLElement>('#slider')!. 199 removeEventListener('mouseup', this.statisticsSliderMouseupHandler); 200 this.startupMode?.removeEventListener('change',this.startupModeChangeHandler); 201 } 202 203 handleInputChange = (ev: KeyboardEvent): void => { 204 // @ts-ignore 205 if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') { 206 ev.preventDefault(); 207 } 208 }; 209 210 initElements(): void { 211 this.filterSize = this.shadowRoot?.querySelector('#filterSized'); 212 this.processId = this.shadowRoot?.getElementById('pid') as LitSelectV; 213 let process = this.processId.shadowRoot?.querySelector('input') as HTMLInputElement; 214 process!.addEventListener('mousedown', () => { 215 this.processMouseDownHandler(process); 216 }); 217 this.unwindEL = this.shadowRoot?.getElementById('unwind') as HTMLInputElement; 218 this.shareMemory = this.shadowRoot?.getElementById('shareMemory') as HTMLInputElement; 219 this.shareMemoryUnit = this.shadowRoot?.getElementById('shareMemoryUnit') as HTMLSelectElement; 220 this.filterMemory = this.shadowRoot?.getElementById('filterSized') as HTMLInputElement; 221 this.fpUnWind = this.shadowRoot?.getElementById('use_fp_unwind') as LitSwitch; 222 this.recordAccurately = this.shadowRoot?.getElementById('use_record_accurately') as LitSwitch; 223 this.offlineSymbol = this.shadowRoot?.getElementById('use_offline_symbolization') as LitSwitch; 224 this.startupMode = this.shadowRoot?.getElementById('use_startup_mode') as LitSwitch; 225 this.responseLibMode = this.shadowRoot?.getElementById('response_lib_mode') as LitSwitch; 226 this.sampleInterval = this.shadowRoot?.getElementById('sample-interval-input') as HTMLInputElement; 227 this.statisticsSlider = this.shadowRoot?.querySelector<LitSlider>('#interval-slider') as LitSlider; 228 this.recordStatisticsResult = this.shadowRoot?.querySelector<HTMLDivElement>( 229 '.record-statistics-result' 230 ) as HTMLDivElement; 231 this.statisticsSlider.sliderStyle = { 232 minRange: 0, 233 maxRange: 3600, 234 defaultValue: '900', 235 resultUnit: 'S', 236 stepSize: 450, 237 lineColor: 'var(--dark-color3,#46B1E3)', 238 buttonColor: '#999999', 239 }; 240 let parentElement = this.statisticsSlider!.parentNode as Element; 241 this.intervalResultInput = this.shadowRoot?.querySelector('.interval-result') as HTMLInputElement; 242 this.intervalResultInput.value = '10'; 243 parentElement.setAttribute('percent', '3600'); 244 this.intervalResultInput.style.color = 'var(--dark-color1,#000000)'; 245 let litSwitch = this.shadowRoot?.querySelector('#switch-disabled') as LitSwitch; 246 litSwitch.addEventListener('change', (event: Event): void => { 247 // @ts-ignore 248 let detail = event.detail; 249 if (detail.checked) { 250 this.unDisable(); 251 } else { 252 this.disable(); 253 } 254 }); 255 this.disable(); 256 } 257 258 startupModeChangeHandler = (): void => { 259 let process = this.processId?.shadowRoot?.querySelector('input') as HTMLInputElement; 260 process.value = ''; 261 if (this.startup_mode) { 262 process!.placeholder = 'please input process'; 263 } else { 264 process!.placeholder = 'please select process'; 265 } 266 }; 267 268 statisticsSliderMouseupHandler = (): void => { 269 setTimeout(() => { 270 let percentValue = this.recordStatisticsResult!.getAttribute('percent'); 271 let index = Math.round(Number(percentValue) / NUM_450); 272 index = index < 1 ? 0 : index; 273 this.intervalResultInput!.value = `${stepValue[index] }`; 274 this.recordStatisticsResult!.setAttribute('percentValue', `${stepValue[index] }`); 275 }); 276 }; 277 278 intervalResultFocusOutHandler = (): void => { 279 let parentElement = this.statisticsSlider!.parentNode as Element; 280 if (this.intervalResultInput!.value.trim() === '') { 281 parentElement.setAttribute('percent', '3600'); 282 this.intervalResultInput!.value = '3600'; 283 this.intervalResultInput!.style.color = 'var(--dark-color,#6a6f77)'; 284 parentElement.setAttribute('percent', this.intervalResultInput!.value); 285 parentElement.setAttribute('percentValue', this.intervalResultInput!.value); 286 this.statisticsSlider!.percent = this.intervalResultInput!.value; 287 let htmlInputElement = this.statisticsSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 288 htmlInputElement.value = this.intervalResultInput!.value; 289 } 290 }; 291 292 statisticsSliderInputHandler = (): void => { 293 this.statisticsSlider!.sliderStyle = { 294 minRange: 0, 295 maxRange: 3600, 296 defaultValue: `${this.recordStatisticsResult!.getAttribute('percent')}`, 297 resultUnit: 'S', 298 stepSize: 450, 299 lineColor: 'var(--dark-color3,#46B1E3)', 300 buttonColor: '#999999', 301 }; 302 this.intervalResultInput!.style.color = 'var(--dark-color1,#000000)'; 303 if (this.recordStatisticsResult!.hasAttribute('percent')) { 304 let step = Math.round(Number(this.recordStatisticsResult!.getAttribute('percent')) / NUM_450); 305 this.recordStatisticsResult!.setAttribute('percentValue', `${stepValue[step]}`); 306 this.intervalResultInput!.value = `${stepValue[step]}`; 307 } 308 }; 309 310 private processMouseDownHandler(process: HTMLInputElement): void { 311 if (this.startSamp) { 312 process.readOnly = false; 313 Cmd.getProcess().then((processList) => { 314 this.processId?.dataSource(processList, ''); 315 if (processList.length > 0 && !this.startup_mode) { 316 this.processId?.dataSource(processList, 'ALL-Process'); 317 } else { 318 this.processId?.dataSource([], ''); 319 } 320 }); 321 } else { 322 process.readOnly = true; 323 return; 324 } 325 if (this.startSamp && (SpRecordTrace.serialNumber === '' || this.startup_mode)) { 326 this.processId?.dataSource([], ''); 327 } else { 328 } 329 } 330 331 intervalResultInputHandler = (): void => { 332 let parentElement = this.statisticsSlider!.parentNode as Element; 333 if (this.recordStatisticsResult!.hasAttribute('percent')) { 334 this.recordStatisticsResult!.removeAttribute('percent'); 335 } 336 this.intervalResultInput!.style.color = 'var(--dark-color1,#000000)'; 337 this.intervalResultInput!.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 338 this.intervalResultInput!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 339 if (this.intervalResultInput!.value.trim() === '') { 340 this.intervalResultInput!.style.color = 'red'; 341 parentElement.setAttribute('percent', '3600'); 342 return; 343 } 344 if (Number(this.intervalResultInput!.value) < this.statisticsSlider!.sliderStyle.minRange || 345 Number(this.intervalResultInput!.value) > this.statisticsSlider!.sliderStyle.maxRange) { 346 this.intervalResultInput!.style.color = 'red'; 347 parentElement.setAttribute('percent', '3600'); 348 } else { 349 let defaultSize = 0; 350 let stepSize = 450; 351 let inputValue = Number(this.intervalResultInput!.value); 352 for (let stepIndex = 0; stepIndex < stepValue.length; stepIndex++) { 353 let currentValue = stepValue[stepIndex]; 354 if (inputValue === currentValue) { 355 defaultSize = stepIndex * stepSize; 356 break; 357 } else if (inputValue < currentValue && stepIndex !== 0) { 358 defaultSize = 359 ((inputValue - stepValue[stepIndex - 1]) / (currentValue - stepValue[stepIndex - 1])) * stepSize + 360 stepSize * (stepIndex - 1); 361 break; 362 } 363 } 364 this.statisticsSlider!.percent = `${defaultSize}`; 365 let htmlInputElement = this.statisticsSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 366 this.statisticsSlider!.sliderStyle = { 367 minRange: 0, 368 maxRange: 3600, 369 defaultValue: `${defaultSize}`, 370 resultUnit: 'S', 371 stepSize: 1, 372 lineColor: 'var(--dark-color3,#46B1E3)', 373 buttonColor: '#999999', 374 }; 375 htmlInputElement.value = `${defaultSize}`; 376 parentElement.setAttribute('percent', this.intervalResultInput!.value); 377 parentElement.setAttribute('percentValue', this.intervalResultInput!.value); 378 } 379 }; 380 381 private unDisable(): void { 382 this.startSamp = true; 383 if (this.fpUnWind) { 384 this.fpUnWind.disabled = false; 385 } 386 if (this.recordAccurately) { 387 this.recordAccurately.disabled = false; 388 } 389 if (this.offlineSymbol) { 390 this.offlineSymbol.disabled = false; 391 } 392 if (this.startupMode) { 393 this.startupMode.disabled = false; 394 } 395 if (this.responseLibMode) { 396 this.responseLibMode.disabled = false; 397 } 398 if (this.sampleInterval) { 399 this.sampleInterval.disabled = false; 400 } 401 this.processId!.removeAttribute('disabled'); 402 let inputBoxes = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.inputBoxes'); 403 inputBoxes!.forEach((item) => { 404 item.disabled = false; 405 }); 406 this.statisticsSlider!.disabled = false; 407 } 408 409 private disable(): void { 410 this.startSamp = false; 411 if (this.fpUnWind) { 412 this.fpUnWind.disabled = true; 413 } 414 if (this.recordAccurately) { 415 this.recordAccurately.disabled = true; 416 } 417 if (this.startupMode) { 418 this.startupMode.disabled = true; 419 } 420 if (this.offlineSymbol) { 421 this.offlineSymbol.disabled = true; 422 } 423 if (this.responseLibMode) { 424 this.responseLibMode.disabled = true; 425 } 426 if (this.sampleInterval) { 427 this.sampleInterval.disabled = true; 428 } 429 this.processId!.setAttribute('disabled', ''); 430 let inputBoxes = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.inputBoxes'); 431 inputBoxes!.forEach((item) => { 432 item.disabled = true; 433 }); 434 this.statisticsSlider!.disabled = true; 435 } 436 437 initHtml(): string { 438 return SpAllocationHtml; 439 } 440} 441 442const stepValue = [0, 1, 10, NUM_30, NUM_60, NUM_300, NUM_600, NUM_1800, NUM_3600]; 443