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