• 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 { LitTable } from '../../../../../base-ui/table/lit-table';
18import { SelectionParam } from '../../../../bean/BoxSelection';
19import { Utils } from '../../base/Utils';
20import { ProcessHistory } from '../../../../bean/AbilityMonitor';
21import { log } from '../../../../../log/Log';
22import { resizeObserver } from '../SheetUtils';
23import { getTabProcessHistoryData } from '../../../../database/sql/ProcessThread.sql';
24
25@element('tabpane-history-processes')
26export class TabPaneHistoryProcesses extends BaseElement {
27  private historyProcessTbl: LitTable | null | undefined;
28  private historyProcessSource: Array<ProcessHistory> = [];
29  private queryHistoryResult: Array<ProcessHistory> = [];
30  private search: HTMLInputElement | undefined | null;
31
32  set data(historyProcessValue: SelectionParam | unknown) {
33    if (this.historyProcessTbl) {
34      // @ts-ignore
35      this.historyProcessTbl.shadowRoot.querySelector('.table').style.height = `${
36        this.parentElement!.clientHeight - 45
37      }px`;
38    }
39    this.queryDataByDB(historyProcessValue);
40  }
41
42  initElements(): void {
43    this.historyProcessTbl = this.shadowRoot?.querySelector<LitTable>('#tb-history-processes');
44    this.historyProcessTbl!.addEventListener('column-click', (evt): void => {
45      // @ts-ignore
46      this.sortByColumn(evt.detail);
47    });
48  }
49
50  connectedCallback(): void {
51    super.connectedCallback();
52    resizeObserver(this.parentElement!, this.historyProcessTbl!);
53  }
54
55  filterData(): void {
56    if (this.queryHistoryResult.length > 0) {
57      let filterHistory = this.queryHistoryResult.filter((item): boolean => {
58        let array = this.toProcessHistoryArray(item); //@ts-ignore
59        let isInclude = array.filter((value): boolean => value.indexOf(this.search!.value) > -1);
60        return isInclude.length > 0;
61      });
62      if (filterHistory.length > 0) {
63        this.historyProcessSource = filterHistory;
64        this.historyProcessTbl!.recycleDataSource = this.historyProcessSource;
65      } else {
66        this.historyProcessSource = [];
67        this.historyProcessTbl!.recycleDataSource = [];
68      }
69    }
70  }
71
72  toProcessHistoryArray(process: ProcessHistory): unknown[] {
73    let array: Array<string> = [];
74    array.push(process.processId.toString());
75    array.push(process.processName);
76    array.push(process.alive);
77    array.push(process.firstSeen);
78    array.push(process.lastSeen);
79    array.push(process.responsibleProcess);
80    array.push(process.userName);
81    array.push(process.cpuTime);
82    return array;
83  }
84
85  queryDataByDB(val: SelectionParam | unknown): void {
86    //@ts-ignore
87    getTabProcessHistoryData(val.leftNs, val.rightNs, val.processId, val.threadId).then((item): void => {
88      if (item.length !== null && item.length > 0) {
89        log(`getTabProcessHistoryData result size : ${item.length}`);
90        for (const processHistory of item) {
91          processHistory.alive = processHistory.alive === '0' ? 'No' : 'Yes';
92          if (Number(processHistory.firstSeen) <= 0) {
93            processHistory.firstSeen = '0:000.000.000';
94            processHistory.firstSeenNumber = 0;
95          } else {
96            processHistory.firstSeenNumber = Number(processHistory.firstSeen);
97            processHistory.firstSeen = Utils.getTimeStampHMS(processHistory.firstSeenNumber);
98          }
99          processHistory.lastSeenNumber = Number(processHistory.lastSeen);
100          processHistory.lastSeen = Utils.getTimeStampHMS(Number(processHistory.lastSeenNumber));
101          processHistory.processName = `${processHistory.processName}(${processHistory.processId})`;
102          processHistory.cpuTimeNumber = Number(processHistory.cpuTime);
103          processHistory.cpuTime = this.timeFormat(processHistory.cpuTimeNumber);
104        }
105        this.historyProcessSource = item;
106        this.queryHistoryResult = item;
107        this.historyProcessTbl!.recycleDataSource = this.historyProcessSource;
108      } else {
109        this.historyProcessSource = [];
110        this.queryHistoryResult = [];
111        this.historyProcessTbl!.recycleDataSource = [];
112      }
113    });
114  }
115
116  timeFormat(ms: number): string {
117    let currentTimeMs = ms;
118    let hours = 3600000;
119    let minute1 = 60000;
120    let second1 = 1000;
121    let res = '';
122    if (currentTimeMs >= hours) {
123      res += `${Math.floor(currentTimeMs / hours)} h `;
124      currentTimeMs = currentTimeMs - Math.floor(currentTimeMs / hours) * hours;
125    }
126    if (currentTimeMs >= minute1) {
127      res += `${Math.floor(currentTimeMs / minute1)} min `;
128      currentTimeMs = currentTimeMs - Math.floor(currentTimeMs / minute1) * minute1;
129    }
130    if (currentTimeMs >= second1) {
131      res += `${Math.floor(currentTimeMs / second1)} s `;
132      currentTimeMs = currentTimeMs - Math.floor(currentTimeMs / second1) * second1;
133    }
134    if (currentTimeMs > 0) {
135      res += `${currentTimeMs} ms `;
136    } else {
137      res += '0 ms ';
138    }
139    return res;
140  }
141
142  initHtml(): string {
143    return `
144<style>
145.history-process-table{
146    height: auto;
147}
148:host{
149    flex-direction: column;
150    display: flex;
151    padding: 10px 10px;
152}
153</style>
154<lit-table id="tb-history-processes" class="history-process-table">
155    <lit-table-column order width="1fr" align="flex-start" title="Process ID" data-index="processId" key="processId"></lit-table-column>
156    <lit-table-column order width="1fr" data-index="alive" key="alive" align="flex-start" title="Alive"></lit-table-column>
157    <lit-table-column order width="1fr" title="First Seen" key="firstSeen" data-index="firstSeen" align="flex-start" ></lit-table-column>
158    <lit-table-column order width="1fr" data-index="lastSeen" key="lastSeen" align="flex-start" title="Last Seen"></lit-table-column>
159    <lit-table-column width="1fr" order title="Process Name" data-index="processName" key="processName" align="flex-start" ></lit-table-column>
160    <lit-table-column order title="Responsible Process" width="1fr" data-index="responsibleProcess" key="responsibleProcess" align="flex-start" ></lit-table-column>
161    <lit-table-column order width="1fr" data-index="userName" title="User ID" key="userName" align="flex-start" ></lit-table-column>
162    <lit-table-column order width="1fr" data-index="cpuTime" key="cpuTime" align="flex-start" title="CPU Time"></lit-table-column>
163</lit-table>
164        `;
165  }
166
167  compare(property: string, sort: number, type: string): unknown {
168    let compareValues = (left: number, right: number): number => {
169      if (sort === 2) {
170        return right - left;
171      } else {
172        return left - right;
173      }
174    };
175
176    return function (historyProcessLeftData: ProcessHistory, historyProcessRightData: ProcessHistory): number {
177      if (type === 'number') {
178        return compareValues(
179          // @ts-ignore
180          parseFloat(historyProcessLeftData[property]),
181          // @ts-ignore
182          parseFloat(historyProcessRightData[property])
183        );
184      } else if (type === 'cpuTime' || type === 'lastSeen' || type === 'firstSeen') {
185        // @ts-ignore
186        return compareValues(historyProcessLeftData[`${type}Number`], historyProcessRightData[`${type}Number`]);
187      } else if (type === 'alive') {
188        // @ts-ignore
189        let leftValue = historyProcessLeftData[property] === 'Yes' ? 1 : 0;
190        // @ts-ignore
191        let rightValue = historyProcessRightData[property] === 'Yes' ? 1 : 0;
192        return compareValues(leftValue, rightValue);
193      } else {
194        // @ts-ignore
195        return compareValues(historyProcessLeftData[property], historyProcessRightData[property]);
196      }
197    };
198  }
199
200  sortByColumn(detail: unknown): void {
201    let type; //@ts-ignore
202    if (detail.key === 'startTime' || detail.key === 'processName') {
203      type = 'string'; //@ts-ignore
204    } else if (detail.key === 'cpuTime') {
205      type = 'cpuTime'; //@ts-ignore
206    } else if (detail.key === 'alive') {
207      type = 'alive';
208    } else {
209      type = 'number';
210    } //@ts-ignore
211    let compareFunction = this.compare(detail.key, detail.sort, type); //@ts-ignore
212    this.historyProcessSource.sort(compareFunction);
213    this.historyProcessTbl!.recycleDataSource = this.historyProcessSource;
214  }
215}
216