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