• 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.js';
17import { checkDesBean, SpCheckDesBox } from './SpCheckDesBox.js';
18import { LitCheckBox, LitCheckBoxChangeEvent } from '../../../base-ui/checkbox/LitCheckBox.js';
19import { LitRadioGroup } from '../../../base-ui/radiobox/LitRadioGroup.js';
20import { info, log } from '../../../log/Log.js';
21import { LitSlider } from '../../../base-ui/slider/LitSlider';
22
23@element('probes-config')
24export class SpProbesConfig extends BaseElement {
25  private traceConfigList: Array<checkDesBean> | undefined;
26  private memoryConfigList: Array<checkDesBean> | undefined;
27  private abilityConfigList: Array<checkDesBean> | undefined;
28  private hitraceConfigList: Array<any> | undefined;
29  private hitrace: SpCheckDesBox | undefined;
30
31  private _traceConfig: HTMLElement | undefined;
32  private _memoryConfig: HTMLElement | undefined | null;
33  private _abilityConfig: HTMLElement | undefined | null;
34  private ftraceBufferSizeResult: HTMLDivElement | null | undefined;
35
36  get traceConfig() {
37    let selectedTrace = this._traceConfig?.querySelectorAll<SpCheckDesBox>(`check-des-box[checked]`) || [];
38    let values = [];
39    for (const litCheckBoxElement of selectedTrace) {
40      values.push(litCheckBoxElement.value);
41    }
42    if (this.hitrace && this.hitrace.checked) {
43      values.push(this.hitrace.value);
44    }
45    info('traceConfig is :', values);
46    return values;
47  }
48
49  get ftraceBufferSize(): number {
50    if (this.ftraceBufferSizeResult?.hasAttribute('percent')) {
51      return Number(this.ftraceBufferSizeResult?.getAttribute('percent'));
52    }
53    return 20480;
54  }
55
56  get memoryConfig() {
57    let values = [];
58    let selectedMemory = this._memoryConfig?.querySelectorAll<SpCheckDesBox>(
59      `check-des-box[checked]`
60    ) as NodeListOf<SpCheckDesBox>;
61    for (const litCheckBoxElement of selectedMemory) {
62      values.push(litCheckBoxElement.value);
63    }
64    log('memoryConfig size is :' + values.length);
65    return values;
66  }
67
68  get recordAbility() {
69    let selectedMemory = this._abilityConfig?.querySelectorAll<SpCheckDesBox>(
70      `check-des-box[checked]`
71    ) as NodeListOf<SpCheckDesBox>;
72    return selectedMemory.length > 0;
73  }
74
75  get traceEvents() {
76    let values = [];
77    if (this.hitrace && this.hitrace.checked) {
78      let parent = this.shadowRoot?.querySelector('.user-events') as Element;
79      const siblingNode = parent?.querySelectorAll<LitCheckBox>(`lit-check-box[name=userEvents][checked]`);
80      for (const litCheckBoxElement of siblingNode) {
81        values.push(litCheckBoxElement.value);
82      }
83    }
84    log('traceEvents size is :' + values.length);
85    return values;
86  }
87
88  get hilogConfig() {
89    let logLevel = this.shadowRoot?.getElementById('logLevel') as LitCheckBox;
90    if (logLevel.checked) {
91      let logRadio = this.shadowRoot?.getElementById('log-radio') as LitRadioGroup;
92      return logRadio.value;
93    } else {
94      return [];
95    }
96  }
97
98  initElements(): void {
99    this.traceConfigList = [
100      {
101        value: 'Scheduling details',
102        isSelect: true,
103        des: 'enables high-detailed tracking of scheduling events',
104      },
105      {
106        value: 'CPU Frequency and idle states',
107        isSelect: true,
108        des: 'Records cpu frequency and idle state change viaftrace',
109      },
110      {
111        value: 'Advanced ftrace config',
112        isSelect: false,
113        des:
114          'Enable individual events and tune the kernel-tracing(ftrace) module.' +
115          'The events enabled here are in addition to those from' +
116          ' enabled by other probes.',
117      },
118    ];
119    this._traceConfig = this.shadowRoot?.querySelector('.trace-config') as HTMLElement;
120    this.traceConfigList.forEach((configBean) => {
121      let checkDesBox = new SpCheckDesBox();
122      checkDesBox.value = configBean.value;
123      checkDesBox.checked = configBean.isSelect;
124      checkDesBox.des = configBean.des;
125      checkDesBox.addEventListener('onchange', () => {
126        this.dispatchEvent(new CustomEvent('addProbe', {}));
127      });
128      this._traceConfig?.appendChild(checkDesBox);
129    });
130    this.memoryConfigList = [
131      {
132        value: 'Kernel meminfo',
133        isSelect: false,
134        des: 'polling of /proc/meminfo',
135      },
136      {
137        value: 'Virtual memory stats',
138        isSelect: false,
139        des:
140          'Periodically polls virtual memory stats from /proc/vmstat.' +
141          ' Allows to gather statistics about swap,' +
142          'eviction, compression and pagecache efficiency',
143      },
144    ];
145    this._memoryConfig = this.shadowRoot?.querySelector('.memory-config');
146    this.memoryConfigList.forEach((configBean) => {
147      let checkDesBox = new SpCheckDesBox();
148      checkDesBox.value = configBean.value;
149      checkDesBox.checked = configBean.isSelect;
150      checkDesBox.des = configBean.des;
151      checkDesBox.addEventListener('onchange', () => {
152        this.dispatchEvent(new CustomEvent('addProbe', {}));
153      });
154      this._memoryConfig?.appendChild(checkDesBox);
155    });
156    this.abilityConfigList = [
157      {
158        value: 'AbilityMonitor',
159        isSelect: false,
160        des: 'Tracks the AbilityMonitor',
161      },
162    ];
163    this._abilityConfig = this.shadowRoot?.querySelector('.ability-config');
164    this.abilityConfigList.forEach((configBean) => {
165      let checkDesBox = new SpCheckDesBox();
166      checkDesBox.value = configBean.value;
167      checkDesBox.checked = configBean.isSelect;
168      checkDesBox.des = configBean.des;
169      checkDesBox.addEventListener('onchange', () => {
170        this.dispatchEvent(new CustomEvent('addProbe', {}));
171      });
172      this._abilityConfig?.appendChild(checkDesBox);
173    });
174
175    this.hitraceConfigList = [
176      { value: 'ability', isSelect: true },
177      { value: 'accesscontrol', isSelect: false },
178      { value: 'accessibility', isSelect: false },
179      { value: 'account', isSelect: false },
180      { value: 'ace', isSelect: true },
181      { value: 'app', isSelect: true },
182      { value: 'ark', isSelect: true },
183      { value: 'binder', isSelect: true },
184      { value: 'commonlibrary', isSelect: false },
185      { value: 'daudio', isSelect: false },
186      { value: 'dcamera', isSelect: false },
187      { value: 'devicemanager', isSelect: false },
188      { value: 'deviceprofile', isSelect: false },
189      { value: 'dhfwk', isSelect: false },
190      { value: 'dinput', isSelect: false },
191      { value: 'disk', isSelect: true },
192      { value: 'dlpcre', isSelect: false },
193      { value: 'dsched', isSelect: false },
194      { value: 'dscreen', isSelect: false },
195      { value: 'dslm', isSelect: false },
196      { value: 'dsoftbus', isSelect: false },
197      { value: 'filemanagement', isSelect: false },
198      { value: 'freq', isSelect: true },
199      { value: 'graphic', isSelect: true },
200      { value: 'gresource', isSelect: false },
201      { value: 'huks', isSelect: false },
202      { value: 'i2c', isSelect: false },
203      { value: 'idle', isSelect: true },
204      { value: 'irq', isSelect: true },
205      { value: 'load', isSelect: false },
206      { value: 'mdfs', isSelect: false },
207      { value: 'memreclaim', isSelect: true },
208      { value: 'misc', isSelect: false },
209      { value: 'mmc', isSelect: true },
210      { value: 'msdp', isSelect: false },
211      { value: 'multimodalinput', isSelect: true },
212      { value: 'net', isSelect: false },
213      { value: 'notification', isSelect: false },
214      { value: 'nweb', isSelect: false },
215      { value: 'ohos', isSelect: true },
216      { value: 'pagecache', isSelect: true },
217      { value: 'power', isSelect: false },
218      { value: 'regulators', isSelect: false },
219      { value: 'rpc', isSelect: true },
220      { value: 'samgr', isSelect: false },
221      { value: 'sched', isSelect: true },
222      { value: 'sensors', isSelect: false },
223      { value: 'sync', isSelect: true },
224      { value: 'ufs', isSelect: false },
225      { value: 'useriam', isSelect: false },
226      { value: 'window', isSelect: true },
227      { value: 'workq', isSelect: true },
228      { value: 'zaudio', isSelect: true },
229      { value: 'zcamera', isSelect: true },
230      { value: 'zimage', isSelect: true },
231      { value: 'zmedia', isSelect: true },
232    ];
233    this.hitrace = this.shadowRoot?.getElementById('hitrace') as SpCheckDesBox;
234    let parent = this.shadowRoot?.querySelector('.user-events') as Element;
235    this.hitraceConfigList?.forEach((hitraceConfig: any) => {
236      let litCheckBox = new LitCheckBox();
237      litCheckBox.setAttribute('name', 'userEvents');
238      litCheckBox.value = hitraceConfig.value;
239      litCheckBox.checked = hitraceConfig.isSelect;
240      litCheckBox.addEventListener('change', (ev: CustomEventInit<LitCheckBoxChangeEvent>) => {
241        let detail = ev.detail;
242        if (this.hitrace?.checked == false) {
243          this.hitrace.checked = detail!.checked;
244        }
245        if (detail!.checked == false && this.hitrace?.checked == true) {
246          let hasChecked = false;
247          const nodes = parent?.querySelectorAll<LitCheckBox>(`lit-check-box[name=userEvents]`);
248          nodes.forEach((vv) => {
249            if (vv.checked) {
250              hasChecked = true;
251            }
252          });
253          if (!hasChecked) {
254            this.hitrace.checked = hasChecked;
255          }
256        }
257        this.dispatchEvent(new CustomEvent('addProbe', {}));
258      });
259      parent.append(litCheckBox);
260    });
261    this.bufferSizeSliderInit();
262  }
263
264  private bufferSizeSliderInit() {
265    let ftraceBufferSizeSlider = this.shadowRoot?.querySelector<LitSlider>('#ftrace-buff-size-slider') as LitSlider;
266    this.ftraceBufferSizeResult = this.shadowRoot?.querySelector('#ftrace-buff-size-div') as HTMLDivElement;
267    ftraceBufferSizeSlider.sliderStyle = {
268      minRange: 2048,
269      maxRange: 307200,
270      defaultValue: '20480',
271      resultUnit: 'KB',
272      stepSize: 2,
273      lineColor: 'var(--dark-color3,#46B1E3)',
274      buttonColor: '#999999',
275    };
276    let ftraceBufferSizeSliderParent = ftraceBufferSizeSlider!.parentNode as Element;
277    let ftraceBuffSizeResultInput = this.shadowRoot?.querySelector('.ftrace-buff-size-result') as HTMLInputElement;
278    ftraceBuffSizeResultInput.value = ftraceBufferSizeSlider.sliderStyle.defaultValue;
279    ftraceBufferSizeSlider.addEventListener('input', (evt) => {
280      ftraceBuffSizeResultInput.parentElement!.classList.remove('border-red');
281      if (this.ftraceBufferSizeResult!.hasAttribute('percent')) {
282        ftraceBuffSizeResultInput.value = Number(this.ftraceBufferSizeResult!.getAttribute('percent')).toString();
283      } else {
284        ftraceBuffSizeResultInput.value = '20480';
285      }
286    });
287    ftraceBufferSizeSliderParent.setAttribute('percent', '20480');
288    ftraceBuffSizeResultInput.style.color = 'var(--dark-color1,#000000)';
289    ftraceBuffSizeResultInput.addEventListener('input', (ev) => {
290      if (this.ftraceBufferSizeResult!.hasAttribute('percent')) {
291        this.ftraceBufferSizeResult!.removeAttribute('percent');
292      }
293      ftraceBuffSizeResultInput.style.color = 'var(--dark-color1,#000000)';
294      ftraceBuffSizeResultInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)';
295      ftraceBuffSizeResultInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)';
296      if (ftraceBuffSizeResultInput.value.trim() == '') {
297        ftraceBuffSizeResultInput.style.color = 'red';
298        ftraceBufferSizeSliderParent.setAttribute('percent', '20480');
299        return;
300      }
301      let ftraceBufferSize = Number(ftraceBuffSizeResultInput.value);
302      if (
303        ftraceBufferSize < ftraceBufferSizeSlider!.sliderStyle.minRange ||
304        ftraceBufferSize > ftraceBufferSizeSlider!.sliderStyle.maxRange
305      ) {
306        ftraceBuffSizeResultInput.parentElement!.classList.add('border-red');
307        ftraceBufferSizeSliderParent.setAttribute('percent', '20480');
308      } else {
309        ftraceBuffSizeResultInput.parentElement!.classList.remove('border-red');
310        ftraceBufferSizeSlider!.percent = ftraceBuffSizeResultInput.value;
311        let htmlInputElement = ftraceBufferSizeSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement;
312        htmlInputElement.value = ftraceBuffSizeResultInput.value;
313        ftraceBufferSizeSliderParent.setAttribute('percent', ftraceBuffSizeResultInput.value);
314        ftraceBufferSizeSliderParent.setAttribute('percentValue', ftraceBuffSizeResultInput.value);
315      }
316    });
317    ftraceBuffSizeResultInput.addEventListener('focusout', (ev) => {
318      if (ftraceBuffSizeResultInput.value.trim() == '') {
319        ftraceBuffSizeResultInput.parentElement!.classList.remove('border-red');
320        ftraceBufferSizeSliderParent.setAttribute('percent', '20480');
321        ftraceBuffSizeResultInput.value = '20480';
322        ftraceBuffSizeResultInput.style.color = 'var(--dark-color,#6a6f77)';
323        ftraceBufferSizeSliderParent.setAttribute('percent', ftraceBuffSizeResultInput.value);
324        ftraceBufferSizeSliderParent.setAttribute('percentValue', ftraceBuffSizeResultInput.value);
325        ftraceBufferSizeSlider!.percent = ftraceBuffSizeResultInput.value;
326        let htmlInputElement = ftraceBufferSizeSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement;
327        htmlInputElement.value = ftraceBuffSizeResultInput.value;
328      }
329    });
330  }
331
332  initHtml(): string {
333    return `
334        <style>
335        .recordText {
336           font-family: Helvetica-Bold;
337           font-size: 1em;
338           color: var(--dark-color1,#000000);
339           line-height: 28px;
340           font-weight: 700;
341           margin-bottom: 20px;
342        }
343
344        :host{
345            display: inline-block;
346            background: var(--dark-background3,#FFFFFF);
347            width: 100%;
348            height: 100%;
349            border-radius: 0px 16px 16px 0px;
350        }
351
352        .root {
353            margin-right: 30px;
354            padding-top: 30px;
355            padding-left: 54px;
356            margin-bottom: 30px;
357            font-size:16px;
358        }
359
360        .config-page {
361            height: 95%;
362            font-size: 0.875em;
363        }
364
365        .trace-config{
366           display: flex;
367           flex-direction: column;
368           width: 50%;
369           gap: 10px;
370           margin-bottom: 20px;
371        }
372
373        .memory-config{
374           display: grid;
375           grid-template-columns: repeat(2, 1fr);
376           border-style: solid none none none;
377           border-color: #D5D5D5;
378           padding-top: 15px;
379           margin-top: 15px;
380           gap: 10px;
381        }
382
383        .ability-config{
384           display: grid;
385           grid-template-columns: repeat(2, 1fr);
386           border-style: solid none none none;
387           border-color: #D5D5D5;
388           padding-top: 15px;
389           margin-top: 15px;
390           gap: 10px;
391        }
392
393        .span-col-2{
394           grid-column: span 2 / auto;
395        }
396
397        .log-config{
398           display: grid;
399           grid-template-columns: repeat(2, 1fr);
400           border-style: solid none none none;
401           border-color: #D5D5D5;
402           padding-top: 15px;
403           gap: 10px;
404        }
405
406        #hitrace-cat{
407           display: grid;
408           grid-template-columns: 1fr 1fr;
409        }
410        .user-events{
411           display: grid;
412           grid-template-columns: repeat(4, 1fr);
413           grid-template-rows: repeat(2, 1fr);
414           gap: 10px;
415           margin-left: 15px;;
416        }
417        #ftrace-buff-size-div {
418            width: 100%;
419            height: min-content;
420            display: grid;
421            grid-template-columns: 1fr min-content;
422        }
423        .buffer-size-des {
424            opacity: 0.6;
425            font-family: Helvetica;
426            font-size: 1em;
427            color: var(--dark-color,#000000);
428            text-align: left;
429            line-height: 20px;
430            font-weight: 400;
431        }
432        .ftrace-buff-size-result-div{
433            display: grid;
434            grid-template-rows: 1fr;
435            grid-template-columns:  min-content min-content;
436            background-color: var(--dark-background5,#F2F2F2);
437            -webkit-appearance:none;
438            color:var(--dark-color,#6a6f77);
439            width: 150px;
440            margin: 0 20px 0 0;
441            height: 40px;
442            border-radius:20px;
443            outline:0;
444            border:1px solid var(--dark-border,#c8cccf);
445        }
446        .ftrace-buff-size-result{
447            background-color: var(--dark-background5,#F2F2F2);
448            -webkit-appearance:none;
449            color:var(--dark-color,#6a6f77);
450            border: none;
451            text-align: center;
452            width: 90px;
453            font-size:14px;
454            outline:0;
455            margin: 5px 0 5px 5px;
456        }
457        .border-red {
458           border:1px solid red;
459        }
460        </style>
461        <div class="root">
462            <div class="recordText" >Record mode</div>
463            <div class="config-page">
464                <div>
465                    <div class="trace-config"></div>
466                    <div class="span-col-2" id="hitrace-cat">
467                      <check-des-box id="hitrace" checked="true" value ="Hitrace categories" des="Enables C++ codebase annotations (HTRACE_BEGIN() / os.Trace())">
468                      </check-des-box>
469                      <div class="user-events">
470                          <slot></slot>
471                      </div>
472                    </div>
473                    <div>
474                       <div>
475                          <p>Buffer Size</p>
476                          <p class="buffer-size-des">The ftrace buffer size range is 2048 KB to 307200 KB</p>
477                       </div>
478                       <div id="ftrace-buff-size-div">
479                          <lit-slider id="ftrace-buff-size-slider" defaultColor="var(--dark-color3,#46B1E3)" open dir="right">
480                          </lit-slider>
481                          <div class='ftrace-buff-size-result-div'>
482                              <input class="ftrace-buff-size-result" type="text" value='20480' onkeyup="this.value=this.value.replace(/\\D/g,'')">
483                              <span style="text-align: center; margin: 8px"> KB </span>
484                           </div>
485                       </div>
486                    </div>
487                </div>
488                <div class="memory-config">
489                    <div class="span-col-2">
490                      <span>Memory Config</span>
491                    </div>
492                </div>
493                <div class="ability-config">
494                    <div class="span-col-2">
495                      <span>Ability Config</span>
496                    </div>
497                </div>
498            </div>
499        </div>
500        `;
501  }
502
503  //当 custom element首次被插入文档DOM时,被调用。
504  public connectedCallback() {
505    let parent = this.shadowRoot?.querySelector('.user-events') as Element;
506    const siblingNode = parent?.querySelectorAll<LitCheckBox>(`lit-check-box[name=userEvents]`);
507    this.hitrace!.addEventListener('onchange', (ev: CustomEventInit<LitCheckBoxChangeEvent>) => {
508      let detail = ev.detail;
509      siblingNode.forEach((node) => {
510        node.checked = detail!.checked;
511      });
512      this.dispatchEvent(new CustomEvent('addProbe', {}));
513    });
514  }
515}
516