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 { SpFFRTConfigHtml } from './SpFFRTConfig.html';
18import { log } from '../../../log/Log';
19import { NUM_16384, NUM_5 } from '../../bean/NumBean';
20import { LitSelectV } from '../../../base-ui/select/LitSelectV';
21import LitSwitch from '../../../base-ui/switch/lit-switch';
22import { LitSelect } from '../../../base-ui/select/LitSelect';
23import { Cmd } from '../../../command/Cmd';
24import { SpRecordTrace } from '../SpRecordTrace';
25
26@element('sp-record-ffrt')
27export class SpFFRTConfig extends BaseElement {
28  private processIdEl: LitSelectV | undefined;
29  private processIdInputEl: HTMLInputElement | undefined;
30  private startupProcessNameEl: LitSelectV | undefined;
31  private restartProcessNameEl: LitSelectV | undefined;
32  private restartProcessNameInputEl: HTMLInputElement | undefined;
33  private useBlockSwitchEl: LitSwitch | undefined;
34  private smbPagesInputEl: HTMLInputElement | undefined;
35  private flushIntervalInputEl: HTMLInputElement | undefined;
36  private clockTypeSelectEl: LitSelect | undefined;
37  private selectProcessNameList: Array<string> = [];
38
39  set startSamp(allocationStart: boolean) {
40    if (allocationStart) {
41      this.setAttribute('startSamp', '');
42    } else {
43      this.removeAttribute('startSamp');
44    }
45  }
46
47  get startSamp(): boolean {
48    return this.hasAttribute('startSamp');
49  }
50
51  get processList(): string {
52    return this.processIdEl!.value || '';
53  }
54
55  get processIds(): number[] {
56    let allPidList: number[] = [];
57    if (this.processIdEl!.value.trim() !== '') {
58      let result = this.processIdEl?.value.match(/\((.+?)\)/g);
59      if (result) {
60        for (let index = 0; index < result.length; index++) {
61          let item = result[index];
62          let currentPid = item!.replace('(', '').replace(')', '');
63          allPidList.push(Number(currentPid));
64        }
65      }
66    }
67    return allPidList;
68  }
69
70  get processNames(): string[] {
71    let allPNameList: string[] = [];
72    if (this.processIdEl!.value.trim() !== '') {
73      let result = this.processIdEl?.value.replace(/[$(\d+)$]/g, '');
74      if (result) {
75        allPNameList = result.split(',');
76      }
77    }
78    if (this.restartProcessNameEl!.value.trim() !== '') {
79      let result = this.restartProcessNameEl?.value.replace(/[$(\d+)$]/g, '');
80      if (result) {
81        allPNameList.push(...result.split(','));
82      }
83    }
84    return allPNameList;
85  }
86
87  get startupProcessNames(): string[] {
88    let allPNameList: string[] = [];
89    if (this.startupProcessNameEl!.value.trim() !== '') {
90      allPNameList = this.startupProcessNameEl!.value.trim().split(',');
91      if (allPNameList.length === 0) {
92        allPNameList = this.startupProcessNameEl!.value.trim().split(';');
93      }
94    }
95    return allPNameList;
96  }
97
98  get restartProcessNames(): string[] {
99    let allPNameList: string[] = [];
100    if (this.restartProcessNameEl!.value.trim() !== '') {
101      let result = this.restartProcessNameEl?.value.replace(/[$(\d+)$]/g, '');
102      if (result) {
103        allPNameList = result.split(',');
104      }
105    }
106    return allPNameList;
107  }
108
109  get useBlock(): boolean {
110    let value = this.useBlockSwitchEl?.checked;
111    if (value !== undefined) {
112      return value;
113    }
114    return true;
115  }
116
117  get smbPages(): number {
118    let value = this.smbPagesInputEl?.value || '';
119    log(`smbPages value is :${value}`);
120    if (value !== '') {
121      return Number(this.smbPagesInputEl?.value) || NUM_16384;
122    }
123    return NUM_16384;
124  }
125
126  get flushInterval(): number {
127    let value = this.flushIntervalInputEl?.value || '';
128    log(`flushInterval value is :${value}`);
129    if (value !== '') {
130      return Number(this.flushIntervalInputEl?.value) || NUM_5;
131    }
132    return NUM_5;
133  }
134
135  get clockType(): string {
136    return this.clockTypeSelectEl?.value || 'BOOTTIME';
137  }
138
139  initElements(): void {
140    this.processIdEl = this.shadowRoot?.getElementById('process-ids') as LitSelectV;
141    this.startupProcessNameEl = this.shadowRoot?.getElementById('startup-process-names') as LitSelectV;
142    this.restartProcessNameEl = this.shadowRoot?.getElementById('restart-process-names') as LitSelectV;
143    this.useBlockSwitchEl = this.shadowRoot?.getElementById('use_block_switch') as LitSwitch;
144    this.smbPagesInputEl = this.shadowRoot?.getElementById('smb-pages') as HTMLInputElement;
145    this.flushIntervalInputEl = this.shadowRoot?.getElementById('flush-interval') as HTMLInputElement;
146    this.clockTypeSelectEl = this.shadowRoot?.getElementById('clock-type') as LitSelect;
147    this.processIdInputEl = this.processIdEl!.shadowRoot?.querySelector('input') as HTMLInputElement;
148    this.restartProcessNameInputEl = this.restartProcessNameEl!.shadowRoot?.querySelector('input') as HTMLInputElement;
149    let litSwitch = this.shadowRoot?.querySelector('#switch-disabled') as LitSwitch;
150    litSwitch.addEventListener('change', (event: Event): void => {
151      // @ts-ignore
152      let detail = event.detail;
153      if (detail.checked) {
154        this.unDisable();
155      } else {
156        this.disable();
157      }
158    });
159    let packageInput = this.startupProcessNameEl!.shadowRoot?.querySelector('input') as HTMLInputElement;
160    packageInput.addEventListener('mousedown', (): void => {
161      this.startupProcessMouseDownHandler(this.startupProcessNameEl, packageInput);
162    });
163    packageInput.value = '';
164    this.disable();
165  }
166
167  initHtml(): string {
168    return SpFFRTConfigHtml;
169  }
170
171  connectedCallback(): void {
172    this.processIdInputEl?.addEventListener('mousedown', this.processMouseDownHandler);
173    this.restartProcessNameInputEl?.addEventListener('mousedown', this.restartProcessMouseDownHandler);
174    this.smbPagesInputEl?.addEventListener('keydown', this.handleInputChangeEvent);
175    this.flushIntervalInputEl?.addEventListener('keydown', this.handleInputChangeEvent);
176  }
177
178  disconnectedCallback(): void {
179    this.processIdInputEl?.removeEventListener('mousedown', this.processMouseDownHandler);
180    this.restartProcessNameInputEl?.removeEventListener('mousedown', this.restartProcessMouseDownHandler);
181    this.smbPagesInputEl?.removeEventListener('keydown', this.handleInputChangeEvent);
182    this.flushIntervalInputEl?.removeEventListener('keydown', this.handleInputChangeEvent);
183  }
184
185  processMouseDownHandler = (): void => {
186    this.setData(this.processIdEl);
187  };
188
189  startupProcessMouseDownHandler(startupPNameEl: LitSelectV | undefined, packageInput: HTMLInputElement): void {
190    if (!startupPNameEl) {
191      return;
192    }
193    let processInputEl = startupPNameEl.shadowRoot?.querySelector('input') as HTMLInputElement;
194    if (this.startSamp) {
195      Cmd.getPackage().then((packageList: string[]): void => {
196        let finalDataList = packageList.map(str => str.replace(/\t/g, ''));
197        if (finalDataList.length > 0) {
198          startupPNameEl.dataSource(finalDataList, 'ALL-Process');
199        } else {
200          startupPNameEl.dataSource([], '');
201        }
202      });
203      processInputEl.readOnly = false;
204    } else {
205      processInputEl.readOnly = true;
206      return;
207    }
208    if (this.startSamp && (SpRecordTrace.serialNumber === '')) {
209      startupPNameEl.dataSource([], '');
210    }
211  };
212
213  restartProcessMouseDownHandler = (): void => {
214    this.setData(this.restartProcessNameEl);
215  };
216
217  handleInputChangeEvent = (ev: KeyboardEvent): void => {
218    // @ts-ignore
219    if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') {
220      ev.preventDefault();
221    }
222  };
223
224  private unDisable(): void {
225    this.startSamp = true;
226    if (this.useBlockSwitchEl) {
227      this.useBlockSwitchEl.disabled = false;
228    }
229    this.processIdEl!.removeAttribute('disabled');
230    this.startupProcessNameEl!.removeAttribute('disabled');
231    this.restartProcessNameEl!.removeAttribute('disabled');
232    this.clockTypeSelectEl!.removeAttribute('disabled');
233    let inputBoxes = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.input-content');
234    inputBoxes!.forEach((item: HTMLInputElement): void => {
235      item.disabled = false;
236    });
237  }
238
239  private disable(): void {
240    this.startSamp = false;
241    if (this.useBlockSwitchEl) {
242      this.useBlockSwitchEl.disabled = true;
243    }
244    this.processIdEl!.setAttribute('disabled', '');
245    this.startupProcessNameEl!.setAttribute('disabled', '');
246    this.restartProcessNameEl!.setAttribute('disabled', '');
247    this.clockTypeSelectEl!.setAttribute('disabled', '');
248    let inputBoxes = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.input-content');
249    inputBoxes!.forEach((item: HTMLInputElement): void => {
250      item.disabled = true;
251    });
252  }
253
254  private setData(selectInputEl: LitSelectV | undefined): void {
255    if (!selectInputEl) {
256      return;
257    }
258    let processInputEl = selectInputEl.shadowRoot?.querySelector('input') as HTMLInputElement;
259    if (this.startSamp) {
260      Cmd.getProcess().then((processList: string[]): void => {
261        selectInputEl.dataSource(processList, '');
262        if (processList.length > 0) {
263          selectInputEl.dataSource(processList, 'ALL-Process');
264        } else {
265          selectInputEl.dataSource([], '');
266        }
267      });
268      processInputEl.readOnly = false;
269    } else {
270      processInputEl.readOnly = true;
271      return;
272    }
273    if (this.startSamp && (SpRecordTrace.serialNumber === '')) {
274      selectInputEl.dataSource([], '');
275    }
276  }
277}
278