• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 { SpCheckDesBox } from './SpCheckDesBox';
18import { LitCheckBox, LitCheckBoxChangeEvent } from '../../../base-ui/checkbox/LitCheckBox';
19import { LitRadioGroup } from '../../../base-ui/radiobox/LitRadioGroup';
20import { info, log } from '../../../log/Log';
21import { LitSlider } from '../../../base-ui/slider/LitSlider';
22import LitSwitch from '../../../base-ui/switch/lit-switch';
23import { SpProbesConfigHtml } from './SpProbesConfig.html';
24
25@element('probes-config')
26export class SpProbesConfig extends BaseElement {
27  private hitrace: SpCheckDesBox | undefined;
28  private _traceConfig: HTMLElement | undefined;
29  private _memoryConfig: HTMLElement | undefined | null;
30  private _abilityConfig: HTMLElement | undefined | null;
31  private ftraceBufferSizeResult: HTMLDivElement | null | undefined;
32  private ftraceSlider: LitSlider | null | undefined;
33
34  private ftraceBuffSizeResultInput: HTMLInputElement | null | undefined;
35
36  set startSamp(allocationStart: boolean) {
37    if (allocationStart) {
38      this.setAttribute('startSamp', '');
39    } else {
40      this.removeAttribute('startSamp');
41    }
42  }
43
44  get startSamp(): boolean {
45    return this.hasAttribute('startSamp');
46  }
47
48  get traceConfig() {
49    let selectedTrace = this._traceConfig?.
50      querySelectorAll<SpCheckDesBox>('check-des-box[checked]') || [];
51    let values = [];
52    for (const litCheckBoxElement of selectedTrace) {
53      values.push(litCheckBoxElement.value);
54    }
55    if (this.hitrace && this.hitrace.checked) {
56      values.push(this.hitrace.value);
57    }
58    info('traceConfig is :', values);
59    return values;
60  }
61
62  get ftraceBufferSize(): number {
63    if (this.ftraceBufferSizeResult?.hasAttribute('percent')) {
64      return Number(this.ftraceBufferSizeResult?.getAttribute('percent'));
65    }
66    return 20480;
67  }
68
69  get memoryConfig() {
70    let values = [];
71    let selectedMemory = this._memoryConfig?.querySelectorAll<SpCheckDesBox>(
72      'check-des-box[checked]'
73    ) as NodeListOf<SpCheckDesBox>;
74    for (const litCheckBoxElement of selectedMemory) {
75      values.push(litCheckBoxElement.value);
76    }
77    log(`memoryConfig size is :${values.length}`);
78    return values;
79  }
80
81  get recordAbility(): boolean {
82    let selectedMemory = this._abilityConfig?.querySelectorAll<SpCheckDesBox>(
83      'check-des-box[checked]'
84    ) as NodeListOf<SpCheckDesBox>;
85    return selectedMemory.length > 0;
86  }
87
88  get traceEvents() {
89    let values = [];
90    if (this.hitrace && this.hitrace.checked) {
91      let parent = this.shadowRoot?.querySelector('.user-events') as Element;
92      const siblingNode = parent?.querySelectorAll<LitCheckBox>('lit-check-box[name=userEvents][checked]');
93      for (const litCheckBoxElement of siblingNode) {
94        values.push(litCheckBoxElement.value);
95      }
96    }
97    log(`traceEvents size is :${values.length}`);
98    return values;
99  }
100
101  get hilogConfig() {
102    let logLevel = this.shadowRoot?.getElementById('logLevel') as LitCheckBox;
103    if (logLevel.checked) {
104      let logRadio = this.shadowRoot?.getElementById('log-radio') as LitRadioGroup;
105      return logRadio.value;
106    } else {
107      return [];
108    }
109  }
110
111  private initTraceConfigList(): void {
112    this._traceConfig = this.shadowRoot?.querySelector('.trace-config') as HTMLElement;
113    traceConfigList.forEach((configBean) => {
114      let checkDesBox = new SpCheckDesBox();
115      checkDesBox.value = configBean.value;
116      checkDesBox.checked = configBean.isSelect;
117      checkDesBox.des = configBean.des;
118      checkDesBox.addEventListener('onchange', () => {
119        this.dispatchEvent(new CustomEvent('addProbe', {}));
120      });
121      this._traceConfig?.appendChild(checkDesBox);
122    });
123  }
124
125  private initMemoryConfigList(): void {
126    this._memoryConfig = this.shadowRoot?.querySelector('.memory-config');
127    memoryConfigList.forEach((configBean) => {
128      let checkDesBox = new SpCheckDesBox();
129      checkDesBox.value = configBean.value;
130      checkDesBox.checked = configBean.isSelect;
131      checkDesBox.des = configBean.des;
132      checkDesBox.addEventListener('onchange', () => {
133        this.dispatchEvent(new CustomEvent('addProbe', {}));
134      });
135      this._memoryConfig?.appendChild(checkDesBox);
136    });
137  }
138
139  private initAbilityConfigList(): void {
140    this._abilityConfig = this.shadowRoot?.querySelector('.ability-config');
141    abilityConfigList.forEach((configBean) => {
142      let checkDesBox = new SpCheckDesBox();
143      checkDesBox.value = configBean.value;
144      checkDesBox.checked = configBean.isSelect;
145      checkDesBox.des = configBean.des;
146      checkDesBox.addEventListener('onchange', () => {
147        this.dispatchEvent(new CustomEvent('addProbe', {}));
148      });
149      this._abilityConfig?.appendChild(checkDesBox);
150    });
151  }
152
153  private initHiTraceConfigList(): void {
154    this.hitrace = this.shadowRoot?.getElementById('hitrace') as SpCheckDesBox;
155    let parent = this.shadowRoot?.querySelector('.user-events') as Element;
156    hiTraceConfigList.forEach((hitraceConfig: any) => {
157      let litCheckBox = new LitCheckBox();
158      litCheckBox.setAttribute('name', 'userEvents');
159      litCheckBox.value = hitraceConfig.value;
160      litCheckBox.checked = hitraceConfig.isSelect;
161      litCheckBox.addEventListener('change', (ev: CustomEventInit<LitCheckBoxChangeEvent>) => {
162        let detail = ev.detail;
163        if (this.hitrace?.checked === false) {
164          this.hitrace.checked = detail!.checked;
165        }
166        if (!detail!.checked && this.hitrace?.checked === true) {
167          let hasChecked = false;
168          const nodes = parent?.querySelectorAll<LitCheckBox>('lit-check-box[name=userEvents]');
169          nodes.forEach((vv) => {
170            if (vv.checked) {
171              hasChecked = true;
172            }
173          });
174          if (!hasChecked) {
175            this.hitrace.checked = hasChecked;
176          }
177        }
178        this.dispatchEvent(new CustomEvent('addProbe', {}));
179      });
180      parent.append(litCheckBox);
181    });
182  }
183
184  initElements(): void {
185    this.ftraceBuffSizeResultInput = this.shadowRoot?.querySelector('.ftrace-buff-size-result') as HTMLInputElement;
186    this.ftraceBuffSizeResultInput!.addEventListener('keydown', (ev: any) => {
187      if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') {
188        ev.preventDefault();
189      }
190    });
191    this.initTraceConfigList();
192    this.initMemoryConfigList();
193    this.initAbilityConfigList();
194    this.initHiTraceConfigList();
195    this.bufferSizeSliderInit();
196    let litSwitch = this.shadowRoot?.querySelector('lit-switch') as LitSwitch;
197    this.ftraceSlider = this.shadowRoot?.querySelector<LitSlider>('#ftrace-buff-size-slider');
198    litSwitch.addEventListener('change', (event: any) => {
199      let detail = event.detail;
200      if (detail!.checked) {
201        this.unDisable();
202      } else {
203        this.disable();
204      }
205    });
206  }
207
208  private bufferSizeSliderInit(): void {
209    let bufferSizeSlider = this.shadowRoot?.querySelector<LitSlider>('#ftrace-buff-size-slider') as LitSlider;
210    this.ftraceBufferSizeResult = this.shadowRoot?.querySelector('#ftrace-buff-size-div') as HTMLDivElement;
211    bufferSizeSlider.sliderStyle = {
212      minRange: 2048,
213      maxRange: 307200,
214      defaultValue: '20480',
215      resultUnit: 'KB',
216      stepSize: 2,
217      lineColor: 'var(--dark-color3,#46B1E3)',
218      buttonColor: '#999999',
219    };
220    let bufferSizeSliderParent = bufferSizeSlider!.parentNode as Element;
221    let buffSizeResult = this.shadowRoot?.querySelector('.ftrace-buff-size-result') as HTMLInputElement;
222    buffSizeResult!.onkeydown = (ev): void => {
223      // @ts-ignore
224      if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') {
225        ev.preventDefault();
226      }
227    };
228    buffSizeResult.value = bufferSizeSlider.sliderStyle.defaultValue;
229    bufferSizeSlider.addEventListener('input', () => {
230      buffSizeResult.parentElement!.classList.remove('border-red');
231      if (this.ftraceBufferSizeResult!.hasAttribute('percent')) {
232        buffSizeResult.value = Number(this.ftraceBufferSizeResult!.getAttribute('percent')).toString();
233      } else {
234        buffSizeResult.value = '20480';
235      }
236    });
237    bufferSizeSliderParent.setAttribute('percent', '20480');
238    buffSizeResult.style.color = 'var(--dark-color1,#000000)';
239    buffSizeResult.addEventListener('input', () => {
240      this.ftraceBuffSizeResultInputHandler(buffSizeResult, bufferSizeSliderParent, bufferSizeSlider);
241    });
242    buffSizeResult.addEventListener('focusout', () => {
243      if (buffSizeResult.value.trim() === '') {
244        buffSizeResult.parentElement!.classList.remove('border-red');
245        bufferSizeSliderParent.setAttribute('percent', '20480');
246        buffSizeResult.value = '20480';
247        buffSizeResult.style.color = 'var(--dark-color,#6a6f77)';
248        bufferSizeSliderParent.setAttribute('percent', buffSizeResult.value);
249        bufferSizeSliderParent.setAttribute('percentValue', buffSizeResult.value);
250        bufferSizeSlider!.percent = buffSizeResult.value;
251        let htmlInputElement = bufferSizeSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement;
252        htmlInputElement.value = buffSizeResult.value;
253      }
254    });
255  }
256
257  private ftraceBuffSizeResultInputHandler(
258    buffSizeResultEl: HTMLInputElement,
259    bufferSizeSliderParentEl: Element,
260    bufferSizeSliderEl: LitSlider
261  ): void {
262    if (this.ftraceBufferSizeResult!.hasAttribute('percent')) {
263      this.ftraceBufferSizeResult!.removeAttribute('percent');
264    }
265    buffSizeResultEl.style.color = 'var(--dark-color1,#000000)';
266    buffSizeResultEl.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)';
267    buffSizeResultEl.style.backgroundColor = 'var(--dark-background5,#F2F2F2)';
268    if (buffSizeResultEl.value.trim() === '') {
269      buffSizeResultEl.style.color = 'red';
270      bufferSizeSliderParentEl.setAttribute('percent', '20480');
271      return;
272    }
273    let ftraceBufferSize = Number(buffSizeResultEl.value);
274    if (
275      ftraceBufferSize < bufferSizeSliderEl!.sliderStyle.minRange ||
276      ftraceBufferSize > bufferSizeSliderEl!.sliderStyle.maxRange
277    ) {
278      buffSizeResultEl.parentElement!.classList.add('border-red');
279      bufferSizeSliderParentEl.setAttribute('percent', '20480');
280    } else {
281      buffSizeResultEl.parentElement!.classList.remove('border-red');
282      bufferSizeSliderEl!.percent = buffSizeResultEl.value;
283      let htmlInputElement = bufferSizeSliderEl!.shadowRoot?.querySelector('#slider') as HTMLInputElement;
284      htmlInputElement.value = buffSizeResultEl.value;
285      bufferSizeSliderParentEl.setAttribute('percent', buffSizeResultEl.value);
286      bufferSizeSliderParentEl.setAttribute('percentValue', buffSizeResultEl.value);
287    }
288  }
289
290  private unDisable(): void {
291    this.startSamp = true;
292    let checkDesBoxDis = this.shadowRoot?.querySelectorAll<SpCheckDesBox>('check-des-box');
293    let litCheckBoxDis = this.shadowRoot?.querySelectorAll<LitCheckBox>('lit-check-box');
294    let defaultSelected: any = [];
295    defaultSelected = defaultSelected.concat(
296      traceConfigList,
297      memoryConfigList,
298      abilityConfigList,
299      hiTraceConfigList
300    );
301    this.shadowRoot?.querySelector<SpCheckDesBox>('[value=\'Hitrace categories\']')?.setAttribute('checked', 'true');
302    this.ftraceSlider!.removeAttribute('disabled');
303    checkDesBoxDis?.forEach((item: SpCheckDesBox) => {
304      item.removeAttribute('disabled');
305    });
306    litCheckBoxDis?.forEach((item: LitCheckBox) => {
307      item.removeAttribute('disabled');
308    });
309    defaultSelected.filter((item: any) => {
310      if (item.isSelect) {
311        this.shadowRoot?.querySelector<SpCheckDesBox>(`[value='${item.value}']`)?.
312          setAttribute('checked', 'true');
313      }
314    });
315  }
316
317  private disable(): void {
318    this.startSamp = false;
319    let checkDesBoxDis = this.shadowRoot?.querySelectorAll<SpCheckDesBox>('check-des-box');
320    let litCheckBoxDis = this.shadowRoot?.querySelectorAll<LitCheckBox>('lit-check-box');
321
322    this.ftraceSlider!.setAttribute('disabled', '');
323
324    checkDesBoxDis?.forEach((item: SpCheckDesBox) => {
325      item.setAttribute('disabled', '');
326      item.checked = false;
327    });
328
329    litCheckBoxDis?.forEach((item: LitCheckBox) => {
330      item.setAttribute('disabled', '');
331      item.checked = false;
332    });
333  }
334
335  initHtml(): string {
336    return SpProbesConfigHtml;
337  }
338
339  //当 custom element首次被插入文档DOM时,被调用。
340  public connectedCallback(): void {
341    let parent = this.shadowRoot?.querySelector('.user-events') as Element;
342    const siblingNode = parent?.querySelectorAll<LitCheckBox>('lit-check-box[name=userEvents]');
343    this.hitrace!.addEventListener('onchange', (ev: CustomEventInit<LitCheckBoxChangeEvent>) => {
344      let detail = ev.detail;
345      siblingNode.forEach((node) => {
346        node.checked = detail!.checked;
347      });
348      this.dispatchEvent(new CustomEvent('addProbe', {}));
349    });
350  }
351}
352
353const hiTraceConfigList = [
354  {value: 'ability', isSelect: true},
355  {value: 'accesscontrol', isSelect: false},
356  {value: 'accessibility', isSelect: false},
357  {value: 'account', isSelect: false},
358  {value: 'ace', isSelect: true},
359  {value: 'app', isSelect: true},
360  {value: 'ark', isSelect: true},
361  {value: 'binder', isSelect: true},
362  {value: 'bluetooth', isSelect: false},
363  {value: 'cloud', isSelect: false},
364  {value: 'commonlibrary', isSelect: false},
365  {value: 'daudio', isSelect: false},
366  {value: 'dcamera', isSelect: false},
367  {value: 'deviceauth', isSelect: false},
368  {value: 'devicemanager', isSelect: false},
369  {value: 'deviceprofile', isSelect: false},
370  {value: 'dhfwk', isSelect: false},
371  {value: 'dinput', isSelect: false},
372  {value: 'disk', isSelect: true},
373  {value: 'distributeddatamgr', isSelect: false},
374  {value: 'dlpcre', isSelect: false},
375  {value: 'dsched', isSelect: false},
376  {value: 'dscreen', isSelect: false},
377  {value: 'dslm', isSelect: false},
378  {value: 'dsoftbus', isSelect: false},
379  {value: 'ffrt', isSelect: false},
380  {value: 'filemanagement', isSelect: false},
381  {value: 'freq', isSelect: true},
382  {value: 'graphic', isSelect: true},
383  {value: 'gresource', isSelect: false},
384  {value: 'hdcd', isSelect: false},
385  {value: 'hdf', isSelect: false},
386  {value: 'huks', isSelect: false},
387  {value: 'i2c', isSelect: false},
388  {value: 'idle', isSelect: true},
389  {value: 'interconn', isSelect: false},
390  {value: 'irq', isSelect: true},
391  {value: 'mdfs', isSelect: false},
392  {value: 'memory', isSelect: false},
393  {value: 'memreclaim', isSelect: true},
394  {value: 'misc', isSelect: false},
395  {value: 'mmc', isSelect: true},
396  {value: 'msdp', isSelect: false},
397  {value: 'multimodalinput', isSelect: true},
398  {value: 'musl', isSelect: false},
399  {value: 'net', isSelect: false},
400  {value: 'notification', isSelect: false},
401  {value: 'nweb', isSelect: false},
402  {value: 'ohos', isSelect: true},
403  {value: 'pagecache', isSelect: true},
404  {value: 'power', isSelect: false},
405  {value: 'regulators', isSelect: false},
406  {value: 'rpc', isSelect: true},
407  {value: 'samgr', isSelect: false},
408  {value: 'sched', isSelect: true},
409  {value: 'sensors', isSelect: false},
410  {value: 'sync', isSelect: true},
411  {value: 'usb', isSelect: false},
412  {value: 'ufs', isSelect: false},
413  {value: 'useriam', isSelect: false},
414  {value: 'virse', isSelect: false},
415  {value: 'window', isSelect: true},
416  {value: 'workq', isSelect: true},
417  {value: 'zaudio', isSelect: true},
418  {value: 'zcamera', isSelect: true},
419  {value: 'zimage', isSelect: true},
420  {value: 'zmedia', isSelect: true},
421];
422
423const traceConfigList = [
424  {
425    value: 'Scheduling details',
426    isSelect: true,
427    des: 'enables high-detailed tracking of scheduling events',
428  },
429  {
430    value: 'CPU Frequency and idle states',
431    isSelect: true,
432    des: 'Records cpu frequency and idle state change viaftrace',
433  },
434  {
435    value: 'Advanced ftrace config',
436    isSelect: false,
437    des:
438      'Enable individual events and tune the kernel-tracing(ftrace) module.' +
439      'The events enabled here are in addition to those from' +
440      ' enabled by other probes.',
441  },
442];
443
444const memoryConfigList = [
445  {
446    value: 'Kernel meminfo',
447    isSelect: false,
448    des: 'polling of /proc/meminfo',
449  },
450  {
451    value: 'Virtual memory stats',
452    isSelect: false,
453    des:
454      'Periodically polls virtual memory stats from /proc/vmstat.' +
455      ' Allows to gather statistics about swap,' +
456      'eviction, compression and pagecache efficiency',
457  },
458];
459
460const abilityConfigList = [
461  {
462    value: 'AbilityMonitor',
463    isSelect: false,
464    des: 'Tracks the AbilityMonitor',
465  },
466];
467