• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 package ohos.devtools.views.distributed;
17 
18 import com.intellij.ui.AncestorListenerAdapter;
19 import com.intellij.ui.components.JBPanel;
20 import net.miginfocom.swing.MigLayout;
21 import ohos.devtools.views.distributed.bean.DistributedFuncBean;
22 import ohos.devtools.views.distributed.bean.DistributedParams;
23 import ohos.devtools.views.distributed.bean.DistributedThreadBean;
24 import ohos.devtools.views.distributed.component.DeviceExpandPanel;
25 import ohos.devtools.views.distributed.component.DistributedTracePanel;
26 import ohos.devtools.views.distributed.component.TraceFuncRow;
27 import ohos.devtools.views.distributed.util.DistributedCache;
28 import ohos.devtools.views.distributed.util.DistributedDB;
29 import ohos.devtools.views.trace.EventDispatcher;
30 import ohos.devtools.views.trace.ExpandPanel;
31 import ohos.devtools.views.trace.Sql;
32 import ohos.devtools.views.trace.Tip;
33 import ohos.devtools.views.trace.util.Utils;
34 
35 import javax.swing.JLayeredPane;
36 import javax.swing.SwingUtilities;
37 import javax.swing.event.AncestorEvent;
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Objects;
41 import java.util.Optional;
42 import java.util.concurrent.CompletableFuture;
43 import java.util.stream.Collectors;
44 
45 /**
46  * DistributedPanel
47  *
48  * @since 2021/7/6 15:36
49  */
50 public class DistributedChartPanel extends JBPanel {
51     /**
52      * JLayeredPane layeredPane
53      */
54     private JLayeredPane layeredPane;
55     private DistributedTracePanel tracePanel;
56     private Tip tip = Tip.getInstance();
57     private DistributedParams params;
58     private JBPanel spacerPanel = new JBPanel();
59 
60     /**
61      * DistributedChartPanel
62      */
DistributedChartPanel()63     public DistributedChartPanel() {
64         setLayout(new MigLayout("insets 0"));
65     }
66 
67     /**
68      * load by paramstest
69      *
70      * @param params params
71      */
load(DistributedParams params)72     public void load(DistributedParams params) {
73         this.params = params;
74         Utils.resetPool();
75         recycleData();
76         DistributedDB.setDbName(params.getPathA(), params.getPathB());
77         DistributedDB.load(true);
78         initUI();
79         EventDispatcher.addThreadRangeListener((startNS, endNS, threadIds) -> {
80             if (threadIds.isEmpty()) {
81                 hideTab();
82             } else {
83                 Optional.ofNullable(DistributedPanel.getTab()).ifPresent(it -> {
84                     displayTab();
85                 });
86             }
87         });
88         EventDispatcher.addClickListener(it -> {
89             if (it instanceof DistributedFuncBean) {
90                 DistributedFuncBean func = (DistributedFuncBean) it;
91                 Optional.ofNullable(DistributedPanel.getTab()).ifPresent(item -> {
92                     displayTab();
93                 });
94             }
95         });
96     }
97 
recycleData()98     private void recycleData() {
99         removeAll();
100         EventDispatcher.clearData();
101         DistributedTracePanel.CURRENT_SELECT_THREAD_IDS.clear();
102         DistributedFuncBean.currentSelectedFunc = null;
103         DistributedCache.recycleData();
104     }
105 
initUI()106     private void initUI() {
107         DistributedCache.setDistribuetedParams(params);
108         CompletableFuture.runAsync(() -> {
109             DistributedDB.getInstance().queryA(Sql.DISTRIBUTED_QUERY_TOTAL_TIME, DistributedCache.DUR_A);
110             DistributedDB.getInstance().queryB(Sql.DISTRIBUTED_QUERY_TOTAL_TIME, DistributedCache.DUR_B);
111             if (DistributedCache.getDistribuetedParams().getOffsetA() != null) {
112                 DistributedDB.getInstance().updateA(Sql.DISTRIBUTED_SET_TRACE_RANGE_START_TIME,
113                     DistributedCache.getDistribuetedParams().getOffsetA());
114             }
115             if (DistributedCache.getDistribuetedParams().getOffsetB() != null) {
116                 DistributedDB.getInstance().updateB(Sql.DISTRIBUTED_SET_TRACE_RANGE_START_TIME,
117                     DistributedCache.getDistribuetedParams().getOffsetB());
118             }
119             if (!DistributedCache.DUR_A.isEmpty() && !DistributedCache.DUR_B.isEmpty()) {
120                 Long totalA = DistributedCache.DUR_A.get(0).getTotal();
121                 Long totalB = DistributedCache.DUR_B.get(0).getTotal();
122                 DistributedTracePanel.setDURATION(Math.max(totalA, totalB));
123                 DistributedTracePanel.startNS = 0;
124                 DistributedTracePanel.endNS = Math.max(totalA, totalB);
125             }
126             SwingUtilities.invokeLater(this::tracePanelInit);
127         }, Utils.getPool()).whenComplete((unused, throwable) -> {
128             if (Objects.nonNull(throwable)) {
129                 throwable.printStackTrace();
130             }
131         });
132     }
133 
tracePanelInit()134     private void tracePanelInit() {
135         setLayout(new MigLayout("insets 0"));
136         tracePanel = new DistributedTracePanel();
137         insertDeviceA();
138         insertDeviceB();
139         tracePanel.getContentPanel().add(spacerPanel, "pushx,growx,h 200!");
140         tracePanel.addAncestorListener(new AncestorListenerAdapter() {
141             @Override
142             public void ancestorAdded(AncestorEvent event) {
143                 super.ancestorAdded(event);
144                 layeredPane = DistributedChartPanel.this.getRootPane().getLayeredPane();
145                 SwingUtilities.invokeLater(() -> {
146                     hideTab();
147                     tip.setJLayeredPane(layeredPane);
148                 });
149             }
150 
151             @Override
152             public void ancestorRemoved(AncestorEvent event) {
153                 super.ancestorRemoved(event);
154                 hideTab();
155                 tip.hidden();
156             }
157         });
158         add(tracePanel, "push,grow");
159     }
160 
insertDeviceA()161     private void insertDeviceA() {
162         DistributedDB.getInstance()
163             .queryA(Sql.DISTRIBUTED_QUERY_THREADS_BY_PID, DistributedCache.THREADS_A, params.getProcessIdA());
164         DistributedCache.setThreadNamesA(DistributedCache.THREADS_A.stream()
165             .collect(Collectors.toMap(th -> th.getTid(), th -> th.getName() == null ? "" : th.getName())));
166         DeviceExpandPanel root =
167             new DeviceExpandPanel(params.getPkgNameA() + " (" + params.getDeviceNameA() + ")", "A");
168         ExpandPanel panel =
169             new ExpandPanel("Process " + params.getProcessIdA() + " (" + DistributedCache.THREADS_A.size() + ")", 110);
170         for (DistributedThreadBean thread : DistributedCache.THREADS_A) {
171             TraceFuncRow<DistributedFuncBean> row = new TraceFuncRow<>(thread.getName(), thread.getTid());
172             row.setRender((g2, data2) -> {
173                 if (data2 != null) {
174                     data2.stream().filter(item -> row.contains(item)).forEach(func -> {
175                         func.setRect(row.getRectByNode(func, 1, row.getFuncHeight()));
176                         func.draw(g2);
177                     });
178                 }
179             });
180             row.setSupplier(() -> {
181                 List<DistributedFuncBean> funcs = new ArrayList<>() {
182                 };
183                 DistributedDB.getInstance().queryA(Sql.DISTRIBUTED_GET_FUN_DATA_BY_TID, funcs, thread.getTid());
184                 funcs.forEach((item) -> {
185                     item.setCurrentType(DistributedFuncBean.BeanDataType.TYPE_A);
186                     DistributedCache.ID_FUNC_BEAN_MAP_A.put(item.getId(), item);
187                 });
188                 DistributedCache.FUNC_MAP_A.put(thread.getTid(), funcs);
189                 int maxDept = funcs.stream().mapToInt(DistributedFuncBean::getDepth).max().orElse(0) + 1;
190                 int maxHeight = maxDept * row.getFuncHeight() + row.getFuncHeight();
191                 if (maxHeight < 30) {
192                     maxHeight = 30;
193                 }
194                 row.setMaxDept(maxDept);
195                 if (panel.getContent().getLayout() instanceof MigLayout) {
196                     MigLayout migLayout = (MigLayout) panel.getContent().getLayout();
197                     migLayout.setComponentConstraints(row, "growx,pushx,h " + maxHeight + "!");
198                 }
199                 row.updateUI();
200                 return funcs;
201             });
202             panel.addTraceRow(row);
203         }
204         root.addRow(panel, "gapleft 5,pushx,growx");
205         tracePanel.getContentPanel().add(root, "pushx,growx");
206     }
207 
insertDeviceB()208     private void insertDeviceB() {
209         DistributedDB.getInstance()
210             .queryB(Sql.DISTRIBUTED_QUERY_THREADS_BY_PID, DistributedCache.THREADS_B, params.getProcessIdB());
211         DistributedCache.setThreadNamesB(DistributedCache.THREADS_B.stream()
212             .collect(Collectors.toMap(th -> th.getTid(), th -> th.getName() == null ? "" : th.getName())));
213         DeviceExpandPanel root =
214             new DeviceExpandPanel(params.getPkgNameB() + " (" + params.getDeviceNameB() + ")", "B");
215         ExpandPanel panel =
216             new ExpandPanel("Process " + params.getProcessIdB() + " (" + DistributedCache.THREADS_B.size() + ")", 110);
217         for (DistributedThreadBean thread : DistributedCache.THREADS_B) {
218             TraceFuncRow<DistributedFuncBean> row = new TraceFuncRow<>(thread.getName(), thread.getTid());
219             row.setRender((g2, data2) -> {
220                 if (data2 != null) {
221                     data2.stream().filter(item -> row.contains(item)).forEach(func -> {
222                         func.setRect(row.getRectByNode(func, 1, row.getFuncHeight()));
223                         func.draw(g2);
224                     });
225                 }
226             });
227             row.setSupplier(() -> {
228                 List<DistributedFuncBean> funcs = new ArrayList<>() {
229                 };
230                 DistributedDB.getInstance().queryB(Sql.DISTRIBUTED_GET_FUN_DATA_BY_TID, funcs, thread.getTid());
231                 funcs.forEach((item) -> {
232                     item.setCurrentType(DistributedFuncBean.BeanDataType.TYPE_B);
233                     DistributedCache.ID_FUNC_BEAN_MAP_B.put(item.getId(), item);
234                 });
235                 DistributedCache.FUNC_MAP_B.put(thread.getTid(), funcs);
236                 int maxDept = funcs.stream().mapToInt(DistributedFuncBean::getDepth).max().orElse(0) + 1;
237                 int maxHeight = maxDept * row.getFuncHeight() + row.getFuncHeight();
238                 if (maxHeight < 30) {
239                     maxHeight = 30;
240                 }
241                 row.setMaxDept(maxDept);
242                 if (panel.getContent().getLayout() instanceof MigLayout) {
243                     MigLayout migLayout = (MigLayout) panel.getContent().getLayout();
244                     migLayout.setComponentConstraints(row, "growx,pushx,h " + maxHeight + "!");
245                 }
246                 row.updateUI();
247                 return funcs;
248             });
249             panel.addTraceRow(row);
250         }
251         root.addRow(panel, "gapleft 5,pushx,growx");
252         tracePanel.getContentPanel().add(root, "pushx,growx");
253     }
254 
hideTab()255     private void hideTab() {
256         if (DistributedPanel.getTab() != null && layeredPane != null) {
257             if (DistributedFuncBean.currentSelectedFunc != null) {
258                 DistributedFuncBean.currentSelectedFunc.setSelected(false);
259                 DistributedFuncBean.currentSelectedFunc = null;
260             }
261             DistributedPanel.getTab().setVisible(false);
262             if (DistributedPanel.getSplitter() != null) {
263                 DistributedPanel.getSplitter().setProportion(1.0f);
264             }
265             tracePanel.getTimeShaft().requestFocusInWindow();
266         }
267     }
268 
displayTab()269     private void displayTab() {
270         if (Objects.nonNull(DistributedPanel.getTab())) {
271             DistributedPanel.getTab().setVisible(true);
272             if (DistributedPanel.getSplitter() != null) {
273                 DistributedPanel.getSplitter().setProportion(0.6f);
274             }
275         }
276     }
277 
setSpacerPanelHeight(int height)278     private void setSpacerPanelHeight(int height) {
279         MigLayout layout = (MigLayout) tracePanel.getContentPanel().getLayout();
280         layout.setComponentConstraints(spacerPanel,
281             "growx,pushx,h " + (height - DistributedPanel.getTab().getBarHeight()) + "!");
282         spacerPanel.updateUI();
283     }
284 }
285