• 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 { log } from '../../../log/Log.js';
18import { HdcDeviceManager } from '../../../hdc/HdcDeviceManager.js';
19import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js';
20import '../../../base-ui/select/LitAllocationSelect.js';
21import { SpApplication } from '../../SpApplication.js';
22import { LitSearch } from '../trace/search/Search.js';
23import { SpRecordTrace } from '../SpRecordTrace.js';
24import { Cmd } from '../../../command/Cmd.js';
25import { CmdConstant } from '../../../command/CmdConstant.js';
26import LitSwitch from '../../../base-ui/switch/lit-switch.js';
27import { LitSlider } from '../../../base-ui/slider/LitSlider';
28
29@element('sp-allocations')
30export class SpAllocations extends BaseElement {
31  private processId: LitAllocationSelect | null | undefined;
32  private unwindEL: HTMLInputElement | null | undefined;
33  private shareMemory: HTMLInputElement | null | undefined;
34  private shareMemoryUnit: HTMLSelectElement | null | undefined;
35  private filterMemory: HTMLInputElement | null | undefined;
36  private filterMemoryUnit: HTMLSelectElement | null | undefined;
37  private fpUnWind: LitSwitch | null | undefined;
38
39  private recordAccurately: LitSwitch | null | undefined;
40  private offlineSymbol: LitSwitch | null | undefined;
41  private recordStatisticsResult: HTMLDivElement | null | undefined;
42
43  get appProcess(): string {
44    return this.processId!.value || '';
45  }
46
47  get unwind(): number {
48    log('unwind value is :' + this.unwindEL!.value);
49    return Number(this.unwindEL!.value);
50  }
51
52  get shared(): number {
53    let value = this.shareMemory?.value || '';
54    log('shareMemory value is :' + value);
55    if (value != '') {
56      let unit = Number(this.shareMemory?.value) || 16384;
57      return unit;
58    }
59    return 16384;
60  }
61
62  get filter(): number {
63    let value = this.filterMemory?.value || '';
64    log('filter value is :' + value);
65    if (value != '') {
66      return Number(value);
67    }
68    return 4096;
69  }
70
71  get fp_unwind(): boolean {
72    let value = this.fpUnWind?.checked;
73    if (value != undefined) {
74      return value;
75    }
76    return true;
77  }
78
79  get record_accurately(): boolean {
80    let value = this.recordAccurately?.checked;
81    if (value != undefined) {
82      return value;
83    }
84    return true;
85  }
86
87  get offline_symbolization(): boolean {
88    let value = this.offlineSymbol?.checked;
89    if (value != undefined) {
90      return value;
91    }
92    return true;
93  }
94
95  get record_statistics(): boolean {
96    if (this.recordStatisticsResult?.hasAttribute('percent')) {
97      let value = Number(this.recordStatisticsResult?.getAttribute('percent'));
98      return value > 0;
99    }
100    return true;
101  }
102
103  get statistics_interval(): number {
104    if (this.recordStatisticsResult?.hasAttribute('percentValue')) {
105      return Number(this.recordStatisticsResult?.getAttribute('percentValue'));
106    }
107    return 3600;
108  }
109
110  initElements(): void {
111    this.processId = this.shadowRoot?.getElementById('pid') as LitAllocationSelect;
112    let input = this.processId.shadowRoot?.querySelector('.multipleSelect') as HTMLDivElement;
113    let sp = document.querySelector('sp-application') as SpApplication;
114    let litSearch = sp?.shadowRoot?.querySelector('#lit-record-search') as LitSearch;
115    let allocationProcessData: Array<string> = [];
116    input.addEventListener('mousedown', (ev) => {
117      if (SpRecordTrace.serialNumber == '') {
118        this.processId!.processData = [];
119      }
120    });
121    input.addEventListener('valuable', (ev) => {
122      this.dispatchEvent(new CustomEvent('addProbe', {}));
123    });
124    input.addEventListener('inputClick', () => {
125      allocationProcessData = [];
126      if (SpRecordTrace.serialNumber != '') {
127        Cmd.getProcess().then((processList) => {
128          this.processId!.processData = processList;
129          this.processId!.initData();
130        });
131      }
132    });
133    this.unwindEL = this.shadowRoot?.getElementById('unwind') as HTMLInputElement;
134    this.shareMemory = this.shadowRoot?.getElementById('shareMemory') as HTMLInputElement;
135    this.shareMemoryUnit = this.shadowRoot?.getElementById('shareMemoryUnit') as HTMLSelectElement;
136    this.filterMemory = this.shadowRoot?.getElementById('filterSized') as HTMLInputElement;
137    this.filterMemoryUnit = this.shadowRoot?.getElementById('filterSizedUnit') as HTMLSelectElement;
138    this.fpUnWind = this.shadowRoot?.getElementById('use_fp_unwind') as LitSwitch;
139    this.recordAccurately = this.shadowRoot?.getElementById('use_record_accurately') as LitSwitch;
140    this.offlineSymbol = this.shadowRoot?.getElementById('use_offline_symbolization') as LitSwitch;
141    let stepValue = [0, 1, 10, 30, 60, 300, 600, 1800, 3600];
142    let statisticsSlider = this.shadowRoot?.querySelector<LitSlider>('#interval-slider') as LitSlider;
143
144    this.recordStatisticsResult = this.shadowRoot?.querySelector<HTMLDivElement>(
145      '.record-statistics-result'
146    ) as HTMLDivElement;
147    statisticsSlider.sliderStyle = {
148      minRange: 0,
149      maxRange: 3600,
150      defaultValue: '3600',
151      resultUnit: 'S',
152      stepSize: 450,
153      lineColor: 'var(--dark-color3,#46B1E3)',
154      buttonColor: '#999999',
155    };
156    let parentElement = statisticsSlider!.parentNode as Element;
157    let intervalResultInput = this.shadowRoot?.querySelector('.interval-result') as HTMLInputElement;
158    intervalResultInput.value = statisticsSlider.sliderStyle.defaultValue;
159    statisticsSlider.addEventListener('input', (evt) => {
160      statisticsSlider!.sliderStyle = {
161        minRange: 0,
162        maxRange: 3600,
163        defaultValue: this.recordStatisticsResult!.getAttribute('percent') + '',
164        resultUnit: 'S',
165        stepSize: 450,
166        lineColor: 'var(--dark-color3,#46B1E3)',
167        buttonColor: '#999999',
168      };
169      intervalResultInput.style.color = 'var(--dark-color1,#000000)';
170      if (this.recordStatisticsResult!.hasAttribute('percent')) {
171        let step = Number(this.recordStatisticsResult!.getAttribute('percent')) / 450;
172        this.recordStatisticsResult!.setAttribute('percentValue', stepValue[step] + '');
173        intervalResultInput.value = stepValue[step] + '';
174      }
175    });
176    parentElement.setAttribute('percent', '3600');
177    intervalResultInput.style.color = 'var(--dark-color1,#000000)';
178    intervalResultInput.addEventListener('input', (ev) => {
179      if (this.recordStatisticsResult!.hasAttribute('percent')) {
180        this.recordStatisticsResult!.removeAttribute('percent');
181      }
182      intervalResultInput.style.color = 'var(--dark-color1,#000000)';
183      intervalResultInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)';
184      intervalResultInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)';
185      if (intervalResultInput.value.trim() == '') {
186        intervalResultInput.style.color = 'red';
187        parentElement.setAttribute('percent', '3600');
188        return;
189      }
190      let memorySize = Number(intervalResultInput.value);
191      if (memorySize < statisticsSlider!.sliderStyle.minRange || memorySize > statisticsSlider!.sliderStyle.maxRange) {
192        intervalResultInput.style.color = 'red';
193        parentElement.setAttribute('percent', '3600');
194      } else {
195        statisticsSlider!.percent = intervalResultInput.value;
196        let htmlInputElement = statisticsSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement;
197        htmlInputElement.value = intervalResultInput.value;
198        statisticsSlider!.sliderStyle = {
199          minRange: 0,
200          maxRange: 3600,
201          defaultValue: intervalResultInput.value,
202          resultUnit: 'S',
203          stepSize: 1,
204          lineColor: 'var(--dark-color3,#46B1E3)',
205          buttonColor: '#999999',
206        };
207        parentElement.setAttribute('percent', intervalResultInput.value);
208        parentElement.setAttribute('percentValue', intervalResultInput.value);
209      }
210    });
211
212    intervalResultInput.addEventListener('focusout', (ev) => {
213      if (intervalResultInput.value.trim() == '') {
214        parentElement.setAttribute('percent', '3600');
215        intervalResultInput.value = '3600';
216        intervalResultInput.style.color = 'var(--dark-color,#6a6f77)';
217        parentElement.setAttribute('percent', intervalResultInput.value);
218        parentElement.setAttribute('percentValue', intervalResultInput.value);
219        statisticsSlider!.percent = intervalResultInput.value;
220        let htmlInputElement = statisticsSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement;
221        htmlInputElement.value = intervalResultInput.value;
222      }
223    });
224    statisticsSlider.shadowRoot?.querySelector<HTMLElement>('#slider')!.addEventListener('mouseup', (ev) => {
225      setTimeout(() => {
226        let percentValue = this.recordStatisticsResult!.getAttribute('percent');
227        let index = Number(percentValue) / 450;
228        index = index < 1 ? 0 : index;
229        intervalResultInput.value = stepValue[index] + '';
230        this.recordStatisticsResult!.setAttribute('percentValue', stepValue[index] + '');
231      });
232    });
233  }
234
235  initHtml(): string {
236    return `
237        <style>
238        .root {
239            padding-top: 45px;
240            margin-left: 40px;
241            display: grid;
242            grid-template-columns: repeat(2, 1fr);
243            grid-template-rows: min-content 1fr min-content;
244            width: 90%;
245            border-radius: 0px 16px 16px 0px;
246        }
247        :host{
248            display: block;
249            width: 100%;
250            border-radius: 0px 16px 16px 0px;
251            height: 100%;
252        }
253        .title {
254            grid-column: span 2 / auto;
255        }
256
257        .font-style{
258            font-family: Helvetica-Bold;
259            font-size: 1em;
260            color: var(--dark-color1,#000000);
261            line-height: 28px;
262            font-weight: 700;
263        }
264        .inner-font-style {
265            font-family: Helvetica,serif;
266            font-size: 1em;
267            color: var(--dark-color1,#000000);
268            text-align: left;
269            line-height: 20px;
270            font-weight: 400;
271            display:flex;
272            width:75%;
273            margin-top: 3px;
274
275        }
276        input {
277           width: 72%;
278           height: 25px;
279           border:0;
280           outline:none;
281           border-radius: 16px;
282           text-indent:2%
283        }
284        input::-webkit-input-placeholder{
285            color:var(--bark-prompt,#999999);
286        }
287        .select {
288            height: 30px;
289            border:0;
290            border-radius: 3px;
291            outline:none;
292            border: 1px solid var(--dark-border,#B3B3B3);
293            width: 60px;
294            background-color:var(--dark-background5, #FFFFFF)
295            font-family: Helvetica;
296            font-size: 14px;
297            color:var(--dark-color,#212121)
298            text-align: center;
299            line-height: 16px;
300            font-weight: 400;
301            border-radius: 16px;
302        }
303        .application{
304           display: flex;
305           flex-direction: column;
306           grid-gap: 15px;
307           margin-top: 40px;
308        }
309        .switchstyle{
310           margin-top: 40px;
311           display: flex;
312        }
313        .inputstyle{
314            background: var(--dark-background5,#FFFFFF);
315            border: 1px solid var(--dark-background5,#999999);
316            font-family: Helvetica;
317            font-size: 14px;
318            color: var(--dark-color1,#212121);
319            text-align: left;
320            line-height: 16px;
321            font-weight: 400;
322        }
323        .inputstyle::-webkit-input-placeholder {
324           background: var(--dark-background5,#FFFFFF);
325        }
326        #one_mb{
327            background-color:var(--dark-background5, #FFFFFF)
328        }
329        #one_kb{
330            background-color:var(--dark-background5, #FFFFFF)
331        }
332        #two_mb{
333            background-color:var(--dark-background5, #FFFFFF)
334        }
335        #two_kb{
336            background-color:var(--dark-background5, #FFFFFF)
337        }
338        .processSelect {
339          border-radius: 15px;
340          width: 84%;
341        }
342        .value-range {
343          opacity: 0.6;
344          font-family: Helvetica;
345          font-size: 1em;
346          color: var(--dark-color,#000000);
347          text-align: left;
348          line-height: 20px;
349          font-weight: 400;
350        }
351        .record-title{
352            margin-bottom: 16px;
353            grid-column: span 3;
354        }
355        #interval-slider {
356            margin: 0 8px;
357            grid-column: span 2;
358        }
359        .resultSize{
360            display: grid;
361            grid-template-rows: 1fr;
362            grid-template-columns:  min-content min-content;
363            background-color: var(--dark-background5,#F2F2F2);
364            -webkit-appearance:none;
365            color:var(--dark-color,#6a6f77);
366            width: 150px;
367            margin: 0 30px 0 0;
368            height: 40px;
369            border-radius:20px;
370            outline:0;
371            border:1px solid var(--dark-border,#c8cccf);
372        }
373        .record-mode{
374            font-family: Helvetica-Bold;
375            font-size: 1em;
376            color: var(--dark-color1,#000000);
377            line-height: 28px;
378            font-weight: 400;
379            margin-bottom: 16px;
380            grid-column: span 1;
381        }
382        .record-prompt{
383              opacity: 0.6;
384              font-family: Helvetica;
385              font-size: 14px;
386              text-align: center;
387              line-height: 35px;
388              font-weight: 400;
389        }
390        .interval-result{
391            background-color: var(--dark-background5,#F2F2F2);
392            -webkit-appearance:none;
393            color:var(--dark-color,#6a6f77);
394            border: none;
395            text-align: center;
396            width: 90px;
397            font-size:14px;
398            outline:0;
399            margin: 5px 0 5px 5px;
400        }
401
402        </style>
403        <div class="root">
404          <div class = "title">
405            <span class="font-style">Native Memory</span>
406          </div>
407          <div class="application">
408             <span class="inner-font-style">ProcessId or ProcessName</span>
409             <span class="value-range">Record process</span>
410             <lit-allocation-select show-search class="processSelect" rounded default-value="" id="pid" placement="bottom" title="process" placeholder="please select process">
411             </lit-allocation-select>
412          </div>
413          <div class="application">
414            <span class="inner-font-style" >Max unwind level</span>
415            <span class="value-range">Max Unwind Level Rang is 0 - 512, default 10</span>
416            <input id= "unwind"  class="inputstyle" type="text" placeholder="Enter the Max Unwind Level" oninput="if(this.value > 512) this.value = '512'" onkeyup="this.value=this.value.replace(/\\D/g,'')" value="10">
417          </div>
418          <div class="application">
419            <span class="inner-font-style">Shared Memory Size (One page equals 4 KB)</span>
420            <span class="value-range">Shared Memory Size Range is 0 - 131072 page, default 16384 page</span>
421            <div>
422              <input id = "shareMemory" class="inputstyle" type="text" placeholder="Enter the Shared Memory Size" oninput="if(this.value > 131072) this.value = '131072'" onkeyup="this.value=this.value.replace(/\\D/g,'')" value="16384">
423              <span>Page</span>
424            </div>
425          </div>
426          <div class="application">
427            <span class="inner-font-style" >Filter Memory Size </span>
428            <span class="value-range">Filter size Range is 0 - 65535 byte, default 4096 byte</span>
429            <div>
430                <input id = "filterSized" class="inputstyle" type="text" placeholder="Enter the Filter Memory Size" oninput="if(this.value > 65535) this.value = '65535'" onkeyup="this.value=this.value.replace(/\\D/g,'')" value="4096">
431                 <span>Byte</span>
432            </div>
433          </div>
434          <div class="switchstyle">
435              <span class="inner-font-style" id="fp-unwind">Use Fp Unwind</span>
436              <lit-switch class="lts" id="use_fp_unwind" title="fp unwind" checked="true"></lit-switch>
437          </div>
438          <div class="switchstyle">
439              <span class="inner-font-style" id="record_accurately ">Use Record Accurately (Available on recent OpenHarmony 4.0)</span>
440              <lit-switch   class="lts" id="use_record_accurately" title="record_accurately" checked="true"></lit-switch>
441          </div>
442          <div class="switchstyle">
443              <span class="inner-font-style" id="offline_symbolization">Use Offline Symbolization (Available on recent OpenHarmony 4.0)</span>
444              <lit-switch   class="lts" id="use_offline_symbolization" title="offline_symbolization" checked="true"></lit-switch>
445          </div>
446
447          <div class="switchstyle record-statistics-result" style="grid-row: 6; grid-column: 1 / 3;height: min-content;display: grid;grid-template-rows: 1fr;grid-template-columns: 1fr min-content;">
448            <div class="record-title">
449                <span class="record-mode">Use Record Statistics (Available on recent OpenHarmony 4.0)</span>
450                <span class="record-prompt"> Time between following interval (0 = disabled) </span>
451            </div>
452            <lit-slider id="interval-slider" defaultColor="var(--dark-color3,#46B1E3)" open dir="right">
453            </lit-slider>
454            <div class='resultSize'>
455                <input class="interval-result" type="text" value='0' onkeyup="this.value=this.value.replace(/\\D/g,'')">
456                <span style="text-align: center; margin: 8px"> S </span>
457            </div>
458          </div>
459        </div>
460        `;
461  }
462
463  private convertToValue(input: string, unit: string): number {
464    let value: number;
465    switch (unit) {
466      case 'MB':
467        value = Number(input) * 1024 * 1024;
468        break;
469      case 'KB':
470        value = Number(input) * 1024;
471        break;
472      default:
473        value = 0;
474    }
475    let number = value / 4096;
476    if (number > 0 && number < 1) {
477      return 16384;
478    }
479    return parseInt(String(number));
480  }
481}
482