1/* 2 * Copyright (C) 2023 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 */ 15import { BaseElement, element } from '../../../../../base-ui/BaseElement'; 16import { type LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; 17import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; 18import '../../../StackBar'; 19import { queryBinderByThreadId } from '../../../../database/sql/ProcessThread.sql'; 20import { Utils } from '../../base/Utils'; 21import { resizeObserver } from '../SheetUtils'; 22import { type BinderGroup, type BinderItem } from '../../../../bean/BinderProcessThread'; 23import { SliceGroup } from '../../../../bean/StateProcessThread'; 24 25@element('tabpane-binders') 26export class TabPaneBinders extends BaseElement { 27 private threadBindersTbl: LitTable | null | undefined; 28 private threadBindersTblSource: Array<SelectionData> = []; 29 private currentSelectionParam: SelectionParam | undefined; 30 31 set data(threadStatesParam: SelectionParam | any) { 32 if (this.currentSelectionParam === threadStatesParam) { 33 return; 34 } 35 this.currentSelectionParam = threadStatesParam; 36 this.initBinderData(threadStatesParam); 37 } 38 39 initBinderData(threadStatesParam: SelectionParam): void { 40 this.threadBindersTbl!.loading = true; 41 this.threadBindersTbl!.recycleDataSource = []; 42 let binderList: BinderItem[] = []; 43 let threadIds = threadStatesParam.threadIds; 44 let processIds: number[] = [...new Set(threadStatesParam.processIds)]; 45 queryBinderByThreadId(processIds, threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then((result) => { 46 if (result !== null && result.length > 0) { 47 binderList = result; 48 } 49 if (binderList.length > 0) { 50 this.threadBindersTbl!.recycleDataSource = this.transferToTreeData(binderList); // @ts-ignore 51 this.threadBindersTblSource = this.threadBindersTbl!.recycleDataSource; 52 this.threadBindersTbl!.loading = false; // @ts-ignore 53 this.tHeadClick(this.threadBindersTbl!.recycleDataSource); 54 } else if (binderList.length === 0) { 55 this.threadBindersTbl!.recycleDataSource = []; 56 this.threadBindersTblSource = []; 57 this.threadBindersTbl!.loading = false; // @ts-ignore 58 this.tHeadClick(this.threadBindersTbl!.recycleDataSource); 59 } 60 }); 61 } 62 63 transferToTreeData(binderList: BinderItem[]): BinderGroup[] { 64 let group: any = {}; 65 binderList.forEach((it: BinderItem) => { 66 if (group[`${it.pid}`]) { 67 let process = group[`${it.pid}`]; 68 process.totalCount += 1; 69 let thread = process.children.find((child: BinderGroup) => child.title === `T-${it.tid}`); 70 if (thread) { 71 thread.totalCount += 1; 72 thread.binderTransactionCount += it.name === 'binder transaction' ? 1 : 0; 73 thread.binderAsyncRcvCount += it.name === 'binder async rcv' ? 1 : 0; 74 thread.binderReplyCount += it.name === 'binder reply' ? 1 : 0; 75 thread.binderTransactionAsyncCount += it.name === 'binder transaction async' ? 1 : 0; 76 } else { 77 process.children.push({ 78 title: `T-${it.tid}`, 79 totalCount: 1, 80 binderTransactionCount: it.name === 'binder transaction' ? 1 : 0, 81 binderAsyncRcvCount: it.name === 'binder async rcv' ? 1 : 0, 82 binderReplyCount: it.name === 'binder reply' ? 1 : 0, 83 binderTransactionAsyncCount: it.name === 'binder transaction async' ? 1 : 0, 84 tid: it.tid, 85 pid: it.pid, 86 }); 87 } 88 } else { 89 group[`${it.pid}`] = { 90 title: `P-${it.pid}`, 91 totalCount: 1, 92 tid: it.tid, 93 pid: it.pid, 94 children: [ 95 { 96 title: `T-${it.tid}`, 97 totalCount: 1, 98 binderTransactionCount: it.name === 'binder transaction' ? 1 : 0, 99 binderAsyncRcvCount: it.name === 'binder async rcv' ? 1 : 0, 100 binderReplyCount: it.name === 'binder reply' ? 1 : 0, 101 binderTransactionAsyncCount: it.name === 'binder transaction async' ? 1 : 0, 102 tid: it.tid, 103 pid: it.pid, 104 }, 105 ], 106 }; 107 } 108 }); 109 return Object.values(group); 110 } 111 112 private tHeadClick(data: Array<SliceGroup>): void { 113 let labels = this.threadBindersTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); 114 if (labels) { 115 for (let i = 0; i < labels.length; i++) { 116 let label = labels[i].innerHTML; 117 labels[i].addEventListener('click', () => { 118 if (label.includes('Process') && i === 0) { 119 this.threadBindersTbl!.setStatus(data, false); 120 this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement( 121 data, 122 RedrawTreeForm.Retract 123 ); 124 } else if (label.includes('Thread') && i === 1) { 125 for (let item of data) { 126 item.status = true; 127 if (item.children !== undefined && item.children.length > 0) { 128 this.threadBindersTbl!.setStatus(item.children, false); 129 } 130 } 131 this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement( 132 data, 133 RedrawTreeForm.Retract 134 ); 135 } 136 }); 137 } 138 } 139 } 140 141 initElements(): void { 142 this.threadBindersTbl = this.shadowRoot?.querySelector<LitTable>('#tb-binder-count'); 143 this.threadBindersTbl!.itemTextHandleMap.set('title', (value) => 144 Utils.transferBinderTitle(value, this.currentSelectionParam?.traceId)); 145 } 146 147 connectedCallback(): void { 148 super.connectedCallback(); 149 resizeObserver(this.parentElement!, this.threadBindersTbl!); 150 } 151 152 initHtml(): string { 153 return ` 154 <style> 155 :host{ 156 padding: 10px 10px; 157 display: flex; 158 flex-direction: column; 159 } 160 #tb-binder-count{ 161 height: auto; 162 overflow-x: auto; 163 width: calc(100vw - 270px) 164 } 165 </style> 166 <lit-table id="tb-binder-count" tree> 167 <lit-table-column title="Process/Thread" data-index="title" key="title" align="flex-start" width="27%" retract> 168 </lit-table-column> 169 <lit-table-column title="Total count" data-index="totalCount" key="totalCount" align="flex-start"> 170 </lit-table-column> 171 <lit-table-column title="Binder transaction count" data-index="binderTransactionCount" key="binderTransactionCount" align="flex-start"> 172 </lit-table-column> 173 <lit-table-column title="Binder transaction async count" data-index="binderTransactionAsyncCount" key="binderTransactionAsyncCount" align="flex-start"> 174 </lit-table-column> 175 <lit-table-column title="Binder reply count" data-index="binderReplyCount" key="binderReplyCount" align="flex-start"> 176 </lit-table-column> 177 <lit-table-column title="Binder async rcv count" data-index="binderAsyncRcvCount" key="binderAsyncRcvCount" align="flex-start"> 178 </lit-table-column> 179 </lit-table> 180 `; 181 } 182} 183