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 '../../../../../base-ui/slicer/lit-slicer'; 20import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; 21import { procedurePool } from '../../../../database/Procedure'; 22import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; 23import { FilterData, TabPaneFilter } from '../TabPaneFilter'; 24import '../TabPaneFilter'; 25import { TabPaneFileSystemEventsHtml } from './TabPaneFileSystemEvents.html'; 26 27@element('tabpane-filesystem-event') 28export class TabPaneFileSystemEvents extends BaseElement { 29 private fsSysEventTbl: LitTable | null | undefined; 30 private fsSysEventTblData: LitTable | null | undefined; 31 private fsSysEventProgressEL: LitProgressBar | null | undefined; 32 private fsSysEventFilter: TabPaneFilter | null | undefined; 33 private fsSysEventLoadingList: number[] = []; 34 private loadingPage: unknown; 35 private fsSysEventSource: Array<FileSysEvent> = []; 36 private fsSysEventFilterSource: Array<FileSysEvent> = []; 37 private fsSysEventSortKey: string = 'startTs'; 38 private fsSysEventSortType: number = 0; 39 private currentSelection: SelectionParam | undefined | null; 40 private filterEventType: string = '0'; 41 private filterProcess: string = '0'; 42 private filterPath: string = '0'; 43 private eventList: string[] | null | undefined; 44 private processList: string[] | null | undefined; 45 private pathList: string[] | null | undefined; 46 47 set data(fsSysEventSelection: SelectionParam | null | undefined) { 48 if (fsSysEventSelection === this.currentSelection) { 49 return; 50 } 51 this.currentSelection = fsSysEventSelection; 52 if (this.fsSysEventTbl) { 53 // @ts-ignore 54 this.fsSysEventTbl.shadowRoot.querySelector('.table').style.height = `${ 55 this.parentElement!.clientHeight - 20 - 31 56 }px`; 57 } 58 if (this.fsSysEventTblData) { 59 // @ts-ignore 60 this.fsSysEventTblData.shadowRoot.querySelector('.table').style.height = `${ 61 this.parentElement!.clientHeight - 20 - 31 62 }px`; 63 } 64 this.filterEventType = '0'; 65 this.filterProcess = '0'; 66 this.queryData(fsSysEventSelection); 67 } 68 69 queryData(fsEventParam: SelectionParam | null | undefined): void { 70 this.fsSysEventTbl!.recycleDataSource = []; 71 this.fsSysEventTblData!.recycleDataSource = []; 72 if (fsEventParam) { 73 this.fsSysEventLoadingList.push(1); 74 this.fsSysEventProgressEL!.loading = true; // @ts-ignore 75 this.loadingPage.style.visibility = 'visible'; 76 this.fsSysEventSource = []; 77 procedurePool.submitWithName( 78 'logic0', 79 'fileSystem-queryFileSysEvents', 80 { 81 leftNs: fsEventParam.leftNs, 82 rightNs: fsEventParam.rightNs, 83 typeArr: fsEventParam.fileSystemType, 84 tab: 'events', 85 }, 86 undefined, 87 (res: unknown) => { 88 // @ts-ignore 89 this.fsSysEventSource = this.fsSysEventSource.concat(res.data); // @ts-ignore 90 res.data = null; // @ts-ignore 91 if (!res.isSending) { 92 this.setProcessFilter(); 93 this.filterData(); 94 this.fsSysEventLoadingList.splice(0, 1); 95 if (this.fsSysEventLoadingList.length === 0) { 96 this.fsSysEventProgressEL!.loading = false; // @ts-ignore 97 this.loadingPage.style.visibility = 'hidden'; 98 } 99 } 100 } 101 ); 102 } 103 } 104 105 setProcessFilter(): void { 106 this.processList = ['All Process']; 107 this.pathList = ['All Path']; 108 this.fsSysEventSource.map((it): void => { 109 if (this.processList!.findIndex((a): boolean => a === it.process) === -1) { 110 this.processList!.push(it.process); 111 } 112 if (this.pathList!.findIndex((a): boolean => a === it.path) === -1) { 113 this.pathList!.push(it.path); 114 } 115 }); 116 this.fsSysEventFilter!.setSelectList(this.eventList, this.processList, '', '', this.pathList, ''); 117 if (this.filterProcess === '-1') { 118 this.filterProcess = `${this.processList.indexOf( 119 // @ts-ignore 120 `${this.currentSelection?.fileSystemFsData.name}[${this.currentSelection?.fileSystemFsData.pid}]` 121 )}`; 122 } 123 this.fsSysEventFilter!.firstSelect = this.filterEventType; 124 this.fsSysEventFilter!.secondSelect = this.filterProcess; 125 this.fsSysEventFilter!.thirdSelect = this.filterPath; 126 } 127 128 filterData(): void { 129 let pfv = parseInt(this.filterProcess); 130 let pathIndex = parseInt(this.filterPath); 131 let eventType = parseInt(this.filterEventType) - 1; 132 this.fsSysEventFilterSource = this.fsSysEventSource.filter((fsEvent: FileSysEvent) => { 133 let pathFilter = true; 134 let eventFilter = fsEvent.type === eventType || eventType === -1; 135 let processFilter = true; 136 if (this.filterPath !== '0') { 137 pathFilter = fsEvent.path === this.pathList![pathIndex]; 138 } 139 if (this.filterProcess !== '0') { 140 processFilter = fsEvent.process === this.processList![pfv]; 141 } 142 return pathFilter && eventFilter && processFilter; 143 }); 144 this.fsSysEventTblData!.recycleDataSource = []; 145 this.sortFsSysEventTable(this.fsSysEventSortKey, this.fsSysEventSortType); 146 } 147 148 initElements(): void { 149 this.loadingPage = this.shadowRoot?.querySelector('.loading'); 150 this.fsSysEventProgressEL = this.shadowRoot?.querySelector('.fs-event-progress') as LitProgressBar; 151 this.fsSysEventTbl = this.shadowRoot?.querySelector<LitTable>('#tbl-filesystem-event'); 152 this.fsSysEventTblData = this.shadowRoot?.querySelector<LitTable>('#tbr-filesystem-event'); 153 this.fsSysEventTbl!.addEventListener('row-click', (fsEventRowClick): void => { 154 // @ts-ignore 155 let data = fsEventRowClick.detail.data as FileSysEvent; // @ts-ignore 156 (data as unknown).isSelected = true; 157 // @ts-ignore 158 if ((fsEventRowClick.detail as unknown).callBack) { 159 // @ts-ignore 160 (fsEventRowClick.detail as unknown).callBack(true); 161 } 162 procedurePool.submitWithName( 163 'logic0', 164 'fileSystem-queryStack', 165 { callchainId: data.callchainId }, 166 undefined, 167 (res: unknown) => { 168 // @ts-ignore 169 this.fsSysEventTblData!.recycleDataSource = res; 170 } 171 ); 172 }); 173 this.fsSysEventTbl!.addEventListener('column-click', (evt): void => { 174 // @ts-ignore 175 this.fsSysEventSortKey = evt.detail.key; 176 // @ts-ignore 177 this.fsSysEventSortType = evt.detail.sort; 178 // @ts-ignore 179 this.sortFsSysEventTable(evt.detail.key, evt.detail.sort); 180 }); 181 this.fsSysEventFilter = this.shadowRoot?.querySelector<TabPaneFilter>('#fs-event-filter'); 182 this.eventList = ['All Event', 'All Open Event', 'All Close Event', 'All Read Event', 'All Write Event']; 183 this.processList = ['All Process']; 184 this.pathList = ['All Path']; 185 this.fsSysEventFilter!.setSelectList(this.eventList, this.processList, '', '', this.pathList, ''); 186 this.fsSysEventFilter!.firstSelect = '0'; 187 this.fsSysEventFilter!.getFilterData((data: FilterData): void => { 188 this.filterEventType = data.firstSelect || '0'; 189 this.filterProcess = data.secondSelect || '0'; 190 this.filterPath = data.thirdSelect || '0'; 191 this.filterData(); 192 }); 193 } 194 195 fromStastics(val: SelectionParam | unknown): void { 196 // @ts-ignore 197 if (val.fileSystemFsData === undefined) { 198 return; 199 } // @ts-ignore 200 if (val.fileSystemFsData.title === 'All') { 201 this.filterEventType = '0'; 202 this.filterProcess = '0'; // @ts-ignore 203 } else if (val.fileSystemFsData.pid === undefined) { 204 // @ts-ignore 205 this.filterEventType = `${val.fileSystemFsData.type + 1}`; 206 this.filterProcess = '0'; 207 } else { 208 // @ts-ignore 209 this.filterEventType = `${val.fileSystemFsData.type + 1}`; 210 this.filterProcess = '-1'; 211 } 212 this.filterPath = '0'; 213 if (this.currentSelection === val) { 214 if (this.filterProcess === '-1') { 215 this.filterProcess = 216 // @ts-ignore 217 `${this.processList?.indexOf(`${val.fileSystemFsData.name}[${val.fileSystemFsData.pid}]`)}`; 218 } 219 this.fsSysEventFilter!.firstSelect = this.filterEventType; 220 this.fsSysEventFilter!.secondSelect = this.filterProcess; 221 this.fsSysEventFilter!.thirdSelect = this.filterPath; 222 this.filterData(); 223 } else { 224 // @ts-ignore 225 this.currentSelection = val; // @ts-ignore 226 this.queryData(val); 227 } 228 } 229 230 connectedCallback(): void { 231 super.connectedCallback(); 232 new ResizeObserver((): void => { 233 if (this.parentElement?.clientHeight !== 0) { 234 if (this.fsSysEventTbl) { 235 // @ts-ignore 236 this.fsSysEventTbl.shadowRoot.querySelector('.table').style.height = `${ 237 this.parentElement!.clientHeight - 10 - 33 238 }px`; 239 this.fsSysEventTbl.reMeauseHeight(); 240 } 241 if (this.fsSysEventTblData) { 242 // @ts-ignore 243 this.fsSysEventTblData.shadowRoot.querySelector('.table').style.height = `${ 244 this.parentElement!.clientHeight - 10 - 33 245 }px`; 246 this.fsSysEventTblData.reMeauseHeight(); 247 } // @ts-ignore 248 this.loadingPage.style.height = `${this.parentElement!.clientHeight - 24}px`; 249 } 250 }).observe(this.parentElement!); 251 } 252 253 sortFsSysEventTable(key: string, type: number): void { 254 if (type === 0) { 255 this.fsSysEventTbl!.recycleDataSource = this.fsSysEventFilterSource; 256 } else { 257 let arr = Array.from(this.fsSysEventFilterSource); 258 arr.sort((fsEventA, fsEventB): number => { 259 if (key === 'startTsStr') { 260 return type === 1 ? fsEventA.startTs - fsEventB.startTs : fsEventB.startTs - fsEventA.startTs; 261 } else if (key === 'durStr') { 262 return type === 1 ? fsEventA.dur - fsEventB.dur : fsEventB.dur - fsEventA.dur; 263 } else if (key === 'process') { 264 return this.sortProcessCase(fsEventA, fsEventB, type); 265 } else if (key === 'thread') { 266 return this.sortThreadCase(fsEventA, fsEventB, type); 267 } else if (key === 'typeStr') { 268 return this.sortTypeCase(fsEventA, fsEventB, type); 269 } else if (key === 'fd') { 270 return type === 1 ? (fsEventA.fd || 0) - (fsEventB.fd || 0) : (fsEventB.fd || 0) - (fsEventA.fd || 0); 271 } else if (key === 'path') { 272 return this.sortPathCase(fsEventA, fsEventB, type); 273 } else { 274 return 0; 275 } 276 }); 277 this.fsSysEventTbl!.recycleDataSource = arr; 278 } 279 } 280 281 private sortPathCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { 282 if (fsEventA.path > fsEventB.path) { 283 return type === 2 ? 1 : -1; 284 } else if (fsEventA.path === fsEventB.path) { 285 return 0; 286 } else { 287 return type === 2 ? -1 : 1; 288 } 289 } 290 291 private sortTypeCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { 292 if (fsEventA.typeStr > fsEventB.typeStr) { 293 return type === 2 ? 1 : -1; 294 } else if (fsEventA.typeStr === fsEventB.typeStr) { 295 return 0; 296 } else { 297 return type === 2 ? -1 : 1; 298 } 299 } 300 301 private sortThreadCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { 302 if (fsEventA.thread > fsEventB.thread) { 303 return type === 2 ? 1 : -1; 304 } else if (fsEventA.thread === fsEventB.thread) { 305 return 0; 306 } else { 307 return type === 2 ? -1 : 1; 308 } 309 } 310 311 private sortProcessCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { 312 if (fsEventA.process > fsEventB.process) { 313 return type === 2 ? 1 : -1; 314 } else if (fsEventA.process === fsEventB.process) { 315 return 0; 316 } else { 317 return type === 2 ? -1 : 1; 318 } 319 } 320 321 initHtml(): string { 322 return TabPaneFileSystemEventsHtml; 323 } 324} 325