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.layout.chartview.memory; 17 18 import com.intellij.icons.AllIcons; 19 import com.intellij.openapi.util.IconLoader; 20 import com.intellij.ui.JBColor; 21 import com.intellij.ui.JBSplitter; 22 import com.intellij.ui.components.JBLabel; 23 import com.intellij.ui.components.JBPanel; 24 import com.intellij.ui.components.JBScrollPane; 25 import com.intellij.ui.table.JBTable; 26 import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; 27 import net.miginfocom.swing.MigLayout; 28 import ohos.devtools.datasources.utils.common.Constant; 29 import ohos.devtools.datasources.utils.device.entity.DeviceIPPortInfo; 30 import ohos.devtools.datasources.utils.device.entity.DeviceType; 31 import ohos.devtools.datasources.utils.process.entity.ProcessInfo; 32 import ohos.devtools.datasources.utils.process.service.ProcessManager; 33 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager; 34 import ohos.devtools.datasources.utils.session.entity.SessionInfo; 35 import ohos.devtools.datasources.utils.session.service.SessionManager; 36 import ohos.devtools.services.memory.agentbean.AgentHeapBean; 37 import ohos.devtools.services.memory.agentbean.MemoryInstanceDetailsInfo; 38 import ohos.devtools.services.memory.agentbean.MemoryInstanceInfo; 39 import ohos.devtools.services.memory.agentdao.MemoryInstanceDetailsManager; 40 import ohos.devtools.services.memory.agentdao.MemoryInstanceManager; 41 import ohos.devtools.views.charts.FilledLineChart; 42 import ohos.devtools.views.charts.ProfilerChart; 43 import ohos.devtools.views.charts.model.ChartDataModel; 44 import ohos.devtools.views.charts.model.ChartDataRange; 45 import ohos.devtools.views.charts.model.ChartLegendColorRect; 46 import ohos.devtools.views.charts.model.ChartStandard; 47 import ohos.devtools.views.charts.tooltip.TooltipItem; 48 import ohos.devtools.views.common.LayoutConstants; 49 import ohos.devtools.views.common.UtConstant; 50 import ohos.devtools.views.common.customcomp.DottedLine; 51 import ohos.devtools.views.common.treetable.ExpandTreeTable; 52 import ohos.devtools.views.layout.chartview.ItemsView; 53 import ohos.devtools.views.layout.chartview.MonitorItemDetail; 54 import ohos.devtools.views.layout.chartview.MonitorItemView; 55 import ohos.devtools.views.layout.chartview.ProfilerChartsView; 56 import ohos.devtools.views.layout.chartview.ProfilerMonitorItem; 57 import ohos.devtools.views.layout.chartview.cpu.CpuItemView; 58 import ohos.devtools.views.layout.chartview.memory.javaagent.AgentTreeTableRowSorter; 59 import ohos.devtools.views.layout.chartview.memory.javaagent.MemoryAgentHeapInfoPanel; 60 import ohos.devtools.views.layout.chartview.memory.javaagent.MemoryTreeTablePanel; 61 import ohos.devtools.views.layout.chartview.memory.nativehook.NativeConfigDialog; 62 import ohos.devtools.views.layout.chartview.observer.MemoryChartObserver; 63 import ohos.devtools.views.layout.dialog.CustomDialog; 64 import ohos.devtools.views.layout.dialog.NativeRecordDialog; 65 import ohos.devtools.views.layout.utils.EventTrackUtils; 66 import org.apache.logging.log4j.LogManager; 67 import org.apache.logging.log4j.Logger; 68 69 import javax.swing.BorderFactory; 70 import javax.swing.BoundedRangeModel; 71 import javax.swing.Icon; 72 import javax.swing.JButton; 73 import javax.swing.JComponent; 74 import javax.swing.JLabel; 75 import javax.swing.JPanel; 76 import javax.swing.JScrollBar; 77 import javax.swing.JTable; 78 import javax.swing.RowSorter; 79 import javax.swing.SortOrder; 80 import javax.swing.SwingUtilities; 81 import javax.swing.SwingWorker; 82 import javax.swing.table.DefaultTableCellRenderer; 83 import javax.swing.table.DefaultTableModel; 84 import javax.swing.table.TableModel; 85 import javax.swing.table.TableRowSorter; 86 import javax.swing.tree.DefaultMutableTreeNode; 87 import java.awt.BorderLayout; 88 import java.awt.Color; 89 import java.awt.Component; 90 import java.awt.Dimension; 91 import java.awt.FlowLayout; 92 import java.awt.Font; 93 import java.awt.event.ComponentAdapter; 94 import java.awt.event.ComponentEvent; 95 import java.awt.event.MouseAdapter; 96 import java.awt.event.MouseEvent; 97 import java.awt.event.MouseMotionAdapter; 98 import java.io.PrintWriter; 99 import java.io.StringWriter; 100 import java.math.BigDecimal; 101 import java.util.ArrayList; 102 import java.util.Arrays; 103 import java.util.Date; 104 import java.util.HashMap; 105 import java.util.LinkedHashMap; 106 import java.util.List; 107 import java.util.Locale; 108 import java.util.Map; 109 import java.util.Objects; 110 import java.util.Vector; 111 import java.util.concurrent.TimeUnit; 112 113 import static ohos.devtools.pluginconfig.NativeConfig.NATIVE_HOOK_PLUGIN_NAME; 114 import static ohos.devtools.views.charts.utils.ChartUtils.divide; 115 import static ohos.devtools.views.layout.chartview.MonitorItemDetail.MEM_CODE; 116 import static ohos.devtools.views.layout.chartview.MonitorItemDetail.MEM_GRAPHICS; 117 import static ohos.devtools.views.layout.chartview.MonitorItemDetail.MEM_JAVA; 118 import static ohos.devtools.views.layout.chartview.MonitorItemDetail.MEM_NATIVE; 119 import static ohos.devtools.views.layout.chartview.MonitorItemDetail.MEM_OTHERS; 120 import static ohos.devtools.views.layout.chartview.MonitorItemDetail.MEM_STACK; 121 import static ohos.devtools.views.layout.chartview.utils.ChartViewConstants.NUM_1024; 122 123 /** 124 * Memory monitor item view 125 * 126 * @since : 2021/10/25 127 */ 128 public class MemoryItemView extends MonitorItemView { 129 /** 130 * memory tootle Legend color 131 */ 132 public static final Color MEMORY_FIRST_PANEL_COLOR = new JBColor(new Color(65, 155, 249), new Color(65, 155, 249)); 133 134 private static final Logger LOGGER = LogManager.getLogger(MemoryItemView.class); 135 136 /** 137 * Splitter PROPORTION 138 */ 139 private static final float PROPORTION_SEGMENT_HEAP = 0.5f; 140 141 /** 142 * instance title width 143 */ 144 private static final int INSTANCE_TITLE_WIDTH = 630; 145 146 /** 147 * instance title height 148 */ 149 private static final int INSTANCE_TITLE_HEIGHT = 34; 150 151 /** 152 * instance pane height 153 */ 154 private static final int INSTANCE_PANE_HEIGHT = 450; 155 156 /** 157 * instance jScrollPane height 158 */ 159 private static final int INSTANCE_SCROLL_HEIGHT = 425; 160 161 /** 162 * instance view width 163 */ 164 private static final float PROPORTION_SEGMENT_VIEW = 0.4f; 165 166 /** 167 * instance view width 168 */ 169 private static final int HEAP_VIEW_PANEL_WIDTH = 410; 170 171 private static final int NUM_418 = 418; 172 173 private static final int NUM_384 = 384; 174 175 private static final int NUM_2 = 2; 176 177 /** 178 * KB,MB转换时的单位 179 */ 180 private static final int UNIT = 1024; 181 182 /** 183 * instanceViewTable 184 */ 185 public JBTable instanceViewTable; 186 187 /** 188 * agentHeapSplitter 189 */ 190 public JBSplitter agentHeapSplitter = new JBSplitter(false, PROPORTION_SEGMENT_HEAP); 191 192 /** 193 * instanceAndDetailSplitter 194 */ 195 public JBSplitter instanceAndDetailSplitter = new JBSplitter(false, PROPORTION_SEGMENT_HEAP); 196 private final JBLabel totalLabel = new JBLabel(); 197 private final ChartLegendColorRect totalColor = new ChartLegendColorRect(); 198 private final JBLabel javaLabel = new JBLabel(); 199 private final ChartLegendColorRect javaColor = new ChartLegendColorRect(); 200 private final JBLabel nativeLabel = new JBLabel(); 201 private final ChartLegendColorRect nativeColor = new ChartLegendColorRect(); 202 private final JBLabel graphicsLabel = new JBLabel(); 203 private final ChartLegendColorRect graphicsColor = new ChartLegendColorRect(); 204 private final JBLabel stackLabel = new JBLabel(); 205 private final ChartLegendColorRect stackColor = new ChartLegendColorRect(); 206 private final JBLabel codeLabel = new JBLabel(); 207 private final ChartLegendColorRect codeColor = new ChartLegendColorRect(); 208 private final JBLabel othersLabel = new JBLabel(); 209 private final ChartLegendColorRect othersColor = new ChartLegendColorRect(); 210 private MemoryChartObserver chartObserver; 211 private JBPanel heapViewPanel; 212 private MemoryTreeTablePanel memoryTreeTablePanel; 213 private JBLabel foldBtn; 214 private JBLabel heapDumpBtn; 215 private JBLabel detailCfgBtn; 216 private JButton nativeBtn; 217 private ProfilerMonitorItem item; 218 219 /** 220 * Constructor 221 */ MemoryItemView()222 public MemoryItemView() { 223 if (ProfilerLogManager.isInfoEnabled()) { 224 LOGGER.info("create MemoryItemView"); 225 } 226 } 227 228 @Override init(ProfilerChartsView bottomPanel, ItemsView parent, ProfilerMonitorItem item)229 public void init(ProfilerChartsView bottomPanel, ItemsView parent, ProfilerMonitorItem item) { 230 this.setName(UtConstant.UT_MEMORY_ITEM_VIEW); 231 this.bottomPanel = bottomPanel; 232 this.parent = parent; 233 this.item = item; 234 this.setLayout(new BorderLayout()); 235 initLegendsComp(); 236 addChart(); 237 MemoryTitleView titleView = new MemoryTitleView(); 238 this.add(titleView, BorderLayout.NORTH); 239 this.addComponentListener(new ComponentAdapter() { 240 @Override 241 public void componentResized(ComponentEvent event) { 242 int height = bottomPanel.getHeight() / 5 * 3; 243 if (heapViewPanel != null) { 244 chart.setPreferredSize(new Dimension(bottomPanel.getWidth(), height)); 245 repaint(); 246 } 247 } 248 }); 249 } 250 initLegendsComp()251 private void initLegendsComp() { 252 if (ProfilerLogManager.isInfoEnabled()) { 253 LOGGER.info("initLegendsComp"); 254 } 255 totalLabel.setOpaque(false); 256 javaLabel.setOpaque(false); 257 nativeLabel.setOpaque(false); 258 graphicsLabel.setOpaque(false); 259 stackLabel.setOpaque(false); 260 codeLabel.setOpaque(false); 261 othersLabel.setOpaque(false); 262 addDivideMouseListener(agentHeapSplitter); 263 addDivideMouseListener(instanceAndDetailSplitter); 264 } 265 266 /** 267 * Splitter Divide add MouseListener 268 * 269 * @param splitter jbSplitter 270 */ addDivideMouseListener(JBSplitter splitter)271 private void addDivideMouseListener(JBSplitter splitter) { 272 splitter.getDivider().addMouseListener(new MouseAdapter() { 273 @Override 274 public void mouseEntered(MouseEvent event) { 275 bottomPanel.getTaskScenePanelChart().getSplitPane().setEnabled(true); 276 } 277 278 @Override 279 public void mouseExited(MouseEvent event) { 280 bottomPanel.getTaskScenePanelChart().getSplitPane().setEnabled(false); 281 } 282 }); 283 } 284 285 /** 286 * Add chart panel 287 */ addChart()288 private void addChart() { 289 if (ProfilerLogManager.isInfoEnabled()) { 290 LOGGER.info("addChart"); 291 } 292 chart = generateChart(); 293 // Register the chart observer to the ProfilerChartsView and listen to the refresh events of the main interface 294 chartObserver = new MemoryChartObserver(chart, bottomPanel.getSessionId(), true); 295 this.bottomPanel.getPublisher().attach(chartObserver); 296 this.add(chart, BorderLayout.CENTER); 297 } 298 generateChart()299 private ProfilerChart generateChart() { 300 ProfilerChart memoryChart = new FilledLineChart(this.bottomPanel, item.getName(), true) { 301 @Override 302 protected void initLegends() { 303 MemoryItemView.this.initChartLegends(legends); 304 } 305 306 @Override 307 protected String getYaxisLabelStr(int value) { 308 // Here we get KB, we need to convert it to MB 309 return value == maxUnitY ? divide(value, UNIT) + " " + axisLabelY : divide(value, UNIT) + ""; 310 } 311 312 @Override 313 protected void buildLegends(List<ChartDataModel> lastModels) { 314 MemoryItemView.this.buildChartLegends(lastModels); 315 } 316 317 @Override 318 protected void buildTooltip(int showKey, int actualKey, boolean newChart) { 319 String totalValue = calcTotal(actualKey, dataMap); 320 List<TooltipItem> tooltipItems = buildTooltipItems(actualKey, dataMap); 321 tooltip.showTip(this, showKey + "", totalValue, tooltipItems, newChart, axisLabelY); 322 } 323 324 @Override 325 protected void leftMouseClickEvent(MouseEvent event) { 326 MemoryItemView.this.chartLeftMouseClick(); 327 } 328 329 @Override 330 protected void rightMouseClickEvent(MouseEvent event) { 331 MemoryItemView.this.chartRightMouseClick(); 332 } 333 334 @Override 335 protected void mouseDraggedEvent(MouseEvent event) { 336 MemoryItemView.this.chartMouseDragged(); 337 } 338 339 @Override 340 protected void mouseReleaseEvent(MouseEvent event) { 341 MemoryItemView.this.chartMouseRelease(); 342 } 343 }; 344 memoryChart.setMaxDisplayX(this.bottomPanel.getPublisher().getStandard().getMaxDisplayMillis()); 345 memoryChart.setMinMarkIntervalX(this.bottomPanel.getPublisher().getStandard().getMinMarkInterval()); 346 memoryChart.setSectionNumY(NUM_2); 347 memoryChart.setAxisLabelY("MB"); 348 memoryChart.setFold(true); 349 memoryChart.setEnableSelect(false); 350 return memoryChart; 351 } 352 353 /** 354 * Init legend components of chart 355 * 356 * @param legends legends 357 */ initChartLegends(JBPanel legends)358 private void initChartLegends(JBPanel legends) { 359 if (ProfilerLogManager.isInfoEnabled()) { 360 LOGGER.info("initChartLegends"); 361 } 362 checkAndAdd(legends, totalColor); 363 checkAndAdd(legends, totalLabel); 364 checkAndAdd(legends, javaColor); 365 checkAndAdd(legends, javaLabel); 366 checkAndAdd(legends, nativeColor); 367 checkAndAdd(legends, nativeLabel); 368 checkAndAdd(legends, graphicsColor); 369 checkAndAdd(legends, graphicsLabel); 370 checkAndAdd(legends, stackColor); 371 checkAndAdd(legends, stackLabel); 372 checkAndAdd(legends, codeColor); 373 checkAndAdd(legends, codeLabel); 374 checkAndAdd(legends, othersColor); 375 checkAndAdd(legends, othersLabel); 376 } 377 checkAndAdd(JBPanel legends, Component component)378 private void checkAndAdd(JBPanel legends, Component component) { 379 if (ProfilerLogManager.isInfoEnabled()) { 380 LOGGER.info("checkAndAdd"); 381 } 382 boolean contain = false; 383 for (Component legend : legends.getComponents()) { 384 if (legend.equals(component)) { 385 contain = true; 386 break; 387 } 388 } 389 if (!contain) { 390 legends.add(component); 391 } 392 component.setVisible(false); 393 } 394 buildChartLegends(List<ChartDataModel> lastModels)395 private void buildChartLegends(List<ChartDataModel> lastModels) { 396 new SwingWorker<>() { 397 @Override 398 protected Object doInBackground() { 399 // Total label 400 BigDecimal totalMB = divide(new BigDecimal(chart.getListSum(lastModels, 0)), new BigDecimal(NUM_1024)); 401 String totalText; 402 if (fold) { 403 String total = totalMB + chart.getAxisLabelY(); 404 totalText = String.format(Locale.ENGLISH, "Total:%s%s", total, chart.getAxisLabelY()); 405 totalColor.setColor(MEMORY_FIRST_PANEL_COLOR); 406 totalColor.setOpaque(false); 407 totalColor.setVisible(true); 408 } else { 409 totalText = String.format(Locale.ENGLISH, "Total:%s%s", totalMB, chart.getAxisLabelY()); 410 totalColor.setVisible(false); 411 } 412 totalLabel.setText(totalText); 413 totalLabel.setVisible(true); 414 // Initialize a map of full memory legends 415 Map<MonitorItemDetail, List<JComponent>> allItemLegendMap = initItemLegends(); 416 // Processing data into legend and remove from allItemLegendMap 417 lastModels.forEach(model -> parseModelToLegend(model, allItemLegendMap)); 418 // There are only unselected monitoring items in the map, which need to be hidden 419 allItemLegendMap 420 .forEach((item, components) -> components.forEach(component -> component.setVisible(false))); 421 return new Object(); 422 } 423 }.execute(); 424 } 425 426 /** 427 * Initialize a map of full memory legends 428 * 429 * @return Map <Monitor item, component of legend> 430 */ initItemLegends()431 private Map<MonitorItemDetail, List<JComponent>> initItemLegends() { 432 if (ProfilerLogManager.isInfoEnabled()) { 433 LOGGER.info("initItemLegends"); 434 } 435 Map<MonitorItemDetail, List<JComponent>> map = new HashMap<>(); 436 map.put(MEM_JAVA, Arrays.asList(javaColor, javaLabel)); 437 map.put(MEM_NATIVE, Arrays.asList(nativeColor, nativeLabel)); 438 map.put(MEM_GRAPHICS, Arrays.asList(graphicsColor, graphicsLabel)); 439 map.put(MEM_STACK, Arrays.asList(stackColor, stackLabel)); 440 map.put(MEM_CODE, Arrays.asList(codeColor, codeLabel)); 441 map.put(MEM_OTHERS, Arrays.asList(othersColor, othersLabel)); 442 return map; 443 } 444 445 /** 446 * Processing data into legend and remove from allItemLegendMap 447 * 448 * @param model Data model 449 * @param allItemLegendMap Map of memory legends 450 */ parseModelToLegend(ChartDataModel model, Map<MonitorItemDetail, List<JComponent>> allItemLegendMap)451 private void parseModelToLegend(ChartDataModel model, Map<MonitorItemDetail, List<JComponent>> allItemLegendMap) { 452 MonitorItemDetail itemParam = MonitorItemDetail.getItemByName(model.getName()); 453 switch (itemParam) { 454 case MEM_JAVA: 455 refreshColorText(javaColor, javaLabel, model); 456 // If the model is saved as the current monitoring item, its components will be displayed 457 allItemLegendMap.get(MEM_JAVA).forEach(component -> component.setVisible(true)); 458 // After the component is set to display, it is removed from the map. After the loop is completed, 459 // only unselected monitoring items are left in the map and need to be hidden 460 allItemLegendMap.remove(MEM_JAVA); 461 break; 462 case MEM_NATIVE: 463 refreshColorText(nativeColor, nativeLabel, model); 464 allItemLegendMap.get(MEM_NATIVE).forEach(component -> component.setVisible(true)); 465 allItemLegendMap.remove(MEM_NATIVE); 466 break; 467 case MEM_GRAPHICS: 468 refreshColorText(graphicsColor, graphicsLabel, model); 469 allItemLegendMap.get(MEM_GRAPHICS).forEach(component -> component.setVisible(true)); 470 allItemLegendMap.remove(MEM_GRAPHICS); 471 break; 472 case MEM_STACK: 473 refreshColorText(stackColor, stackLabel, model); 474 allItemLegendMap.get(MEM_STACK).forEach(component -> component.setVisible(true)); 475 allItemLegendMap.remove(MEM_STACK); 476 break; 477 case MEM_CODE: 478 refreshColorText(codeColor, codeLabel, model); 479 allItemLegendMap.get(MEM_CODE).forEach(component -> component.setVisible(true)); 480 allItemLegendMap.remove(MEM_CODE); 481 break; 482 case MEM_OTHERS: 483 refreshColorText(othersColor, othersLabel, model); 484 allItemLegendMap.get(MEM_OTHERS).forEach(component -> component.setVisible(true)); 485 allItemLegendMap.remove(MEM_OTHERS); 486 break; 487 default: 488 break; 489 } 490 } 491 492 /** 493 * Update the color and text of the legend 494 * 495 * @param colorRect Color component 496 * @param label text label 497 * @param model data 498 */ refreshColorText(ChartLegendColorRect colorRect, JBLabel label, ChartDataModel model)499 private void refreshColorText(ChartLegendColorRect colorRect, JBLabel label, ChartDataModel model) { 500 if (ProfilerLogManager.isInfoEnabled()) { 501 LOGGER.info("refreshColorText"); 502 } 503 String showValue = divide(model.getValue(), NUM_1024).toString(); 504 String text = String.format(Locale.ENGLISH, "%s:%s%s", model.getName(), showValue, chart.getAxisLabelY()); 505 colorRect.setColor(model.getColor()); 506 if (!label.getText().equals(text)) { 507 label.setText(text); 508 } 509 } 510 511 /** 512 * Calculate the total value at a time 513 * 514 * @param time 时间 515 * @param dataMap dataMap 516 * @return Total值 517 */ calcTotal(int time, LinkedHashMap<Integer, List<ChartDataModel>> dataMap)518 private String calcTotal(int time, LinkedHashMap<Integer, List<ChartDataModel>> dataMap) { 519 if (ProfilerLogManager.isInfoEnabled()) { 520 LOGGER.info("calcTotal"); 521 } 522 List<ChartDataModel> models = dataMap.get(time); 523 if (models == null || models.size() == 0) { 524 return ""; 525 } 526 // Here we get KB, we need to convert it to MB 527 int value = chart.getListSum(models, 0); 528 return divide(value, NUM_1024).toString(); 529 } 530 531 /** 532 * Build tooltip items 533 * 534 * @param time Current time 535 * @param dataMap dataMap 536 * @return List 537 */ buildTooltipItems(int time, LinkedHashMap<Integer, List<ChartDataModel>> dataMap)538 private List<TooltipItem> buildTooltipItems(int time, LinkedHashMap<Integer, List<ChartDataModel>> dataMap) { 539 if (ProfilerLogManager.isInfoEnabled()) { 540 LOGGER.info("buildTooltipItems"); 541 } 542 List<TooltipItem> tooltipItems = new ArrayList<>(); 543 if (dataMap == null || dataMap.size() == 0 || dataMap.get(time) == null) { 544 return tooltipItems; 545 } 546 for (ChartDataModel model : dataMap.get(time)) { 547 BigDecimal showValue = divide(model.getValue(), NUM_1024); 548 String text = String.format(Locale.ENGLISH, "%s:%s%s", model.getName(), showValue, chart.getAxisLabelY()); 549 TooltipItem tooltipItem = new TooltipItem(model.getColor(), text); 550 tooltipItems.add(tooltipItem); 551 } 552 return tooltipItems; 553 } 554 555 /** 556 * chartLeftMouseClick 557 */ chartLeftMouseClick()558 private void chartLeftMouseClick() { 559 if (ProfilerLogManager.isInfoEnabled()) { 560 LOGGER.info("chartLeftMouseClick"); 561 } 562 long sessionId = this.bottomPanel.getSessionId(); 563 SessionInfo sessionInfo = SessionManager.getInstance().getSessionInfo(sessionId); 564 if (!sessionInfo.isOfflineMode() 565 && sessionInfo.getDeviceIPPortInfo().getDeviceType() == DeviceType.LEAN_HOS_DEVICE) { 566 return; 567 } 568 if (memoryTreeTablePanel != null) { 569 refreshAgentHeapInfo(sessionId); 570 } else { 571 memoryTreeTablePanel = new MemoryTreeTablePanel(this, sessionId, item.getName()); 572 parent.itemChartClick(this); 573 instanceAndDetailSplitter.setOpaque(true); 574 memoryTreeTablePanel.setOpaque(true); 575 agentHeapSplitter.setFirstComponent(memoryTreeTablePanel); 576 // heapView external total panel 577 heapViewPanel = new JBPanel(); 578 int height = bottomPanel.getHeight() / 5 * 2; 579 heapViewPanel.setPreferredSize(new Dimension(bottomPanel.getWidth(), height)); 580 heapViewPanel.setLayout(new MigLayout("insets 0", "[grow,fill]", "[grow,fill]")); 581 heapViewPanel.add(agentHeapSplitter, "span"); 582 } 583 this.add(heapViewPanel, BorderLayout.SOUTH); 584 } 585 586 /** 587 * refresh agent heap info 588 * 589 * @param sessionId sessionId 590 */ refreshAgentHeapInfo(long sessionId)591 private void refreshAgentHeapInfo(long sessionId) { 592 SwingUtilities.invokeLater(new Runnable() { 593 @Override 594 public void run() { 595 if (ProfilerLogManager.isInfoEnabled()) { 596 LOGGER.info("refreshAgentHeapInfo"); 597 } 598 if (memoryTreeTablePanel != null) { 599 MemoryAgentHeapInfoPanel memoryAgentHeapInfoPanel = 600 memoryTreeTablePanel.getMemoryAgentHeapInfoPanel(); 601 if (memoryAgentHeapInfoPanel != null && memoryAgentHeapInfoPanel.getTreeTable() != null) { 602 DefaultMutableTreeNode root = memoryAgentHeapInfoPanel.initData(sessionId, item.getName()); 603 ListTreeTableModelOnColumns tableModelOnColumns = 604 new ListTreeTableModelOnColumns(root, memoryAgentHeapInfoPanel.columns); 605 ExpandTreeTable agentTreeTable = memoryAgentHeapInfoPanel.getTreeTable(); 606 agentTreeTable.setModel(tableModelOnColumns); 607 JScrollBar scrollBar = agentTreeTable.getVerticalScrollBar(); 608 scrollBar.setValue(0); 609 scrollBar.removeMouseMotionListener(memoryAgentHeapInfoPanel.getMouseMotionAdapter()); 610 createMouseMotionAdapter(memoryAgentHeapInfoPanel, tableModelOnColumns, agentTreeTable); 611 scrollBar.addMouseMotionListener(memoryAgentHeapInfoPanel.getMouseMotionAdapter()); 612 AgentTreeTableRowSorter sorter = 613 new AgentTreeTableRowSorter(agentTreeTable.getTable().getModel()); 614 sorter.setListener((columnIndex, sortOrder) -> { 615 if (columnIndex <= 0 || columnIndex > memoryAgentHeapInfoPanel.columns.length) { 616 return; 617 } 618 if (sortOrder == SortOrder.ASCENDING) { 619 AgentTreeTableRowSorter.sortDescTree(memoryAgentHeapInfoPanel, 620 memoryAgentHeapInfoPanel.columns[columnIndex].getName(), tableModelOnColumns); 621 } else { 622 AgentTreeTableRowSorter.sortTree(memoryAgentHeapInfoPanel, 623 memoryAgentHeapInfoPanel.columns[columnIndex].getName(), tableModelOnColumns); 624 } 625 tableModelOnColumns.reload(); 626 }); 627 agentTreeTable.getTable().setRowSorter(sorter); 628 agentHeapSplitter.setSecondComponent(new JBSplitter(false, 1)); 629 } 630 } 631 } 632 }); 633 } 634 createMouseMotionAdapter(MemoryAgentHeapInfoPanel memoryAgentHeapInfoPanel, ListTreeTableModelOnColumns tableModelOnColumns, ExpandTreeTable agentTreeTable)635 private void createMouseMotionAdapter(MemoryAgentHeapInfoPanel memoryAgentHeapInfoPanel, 636 ListTreeTableModelOnColumns tableModelOnColumns, ExpandTreeTable agentTreeTable) { 637 memoryAgentHeapInfoPanel.setMouseMotionAdapter(new MouseMotionAdapter() { 638 @Override 639 public void mouseDragged(MouseEvent mouseEvent) { 640 JScrollBar jScrollBar = null; 641 Object sourceObject = mouseEvent.getSource(); 642 if (sourceObject instanceof JScrollBar) { 643 jScrollBar = (JScrollBar) sourceObject; 644 BoundedRangeModel model = jScrollBar.getModel(); 645 if (model.getExtent() + model.getValue() == model.getMaximum()) { 646 ListTreeTableModelOnColumns nodeModel = null; 647 Object modelObject = agentTreeTable.getTree().getModel(); 648 if (modelObject instanceof ListTreeTableModelOnColumns) { 649 nodeModel = (ListTreeTableModelOnColumns) modelObject; 650 DefaultMutableTreeNode rootNode = null; 651 Object rootObject = nodeModel.getRoot(); 652 if (rootObject instanceof DefaultMutableTreeNode) { 653 rootNode = (DefaultMutableTreeNode) rootObject; 654 int index = memoryAgentHeapInfoPanel.getAllAgentDatas() 655 .indexOf(memoryAgentHeapInfoPanel.getLastDataNode()); 656 List<AgentHeapBean> list = memoryAgentHeapInfoPanel 657 .listCopy(memoryAgentHeapInfoPanel.getAllAgentDatas(), index, index + 20); 658 for (AgentHeapBean agentDataNode : list) { 659 DefaultMutableTreeNode defaultMutableTreeNode = 660 new DefaultMutableTreeNode(agentDataNode); 661 tableModelOnColumns 662 .insertNodeInto(defaultMutableTreeNode, rootNode, rootNode.getChildCount()); 663 memoryAgentHeapInfoPanel.setLastDataNode(agentDataNode); 664 } 665 } 666 } 667 } 668 } 669 } 670 }); 671 } 672 673 /** 674 * Secondary treeTable interface 675 * 676 * @param sessionId sessionId 677 * @param clazzId clazzId 678 * @param className className 679 * @param chartName chartName 680 * @return JBPanel 681 */ setSecondLevelTreeTable(long sessionId, int clazzId, String className, String chartName)682 public JBPanel setSecondLevelTreeTable(long sessionId, int clazzId, String className, String chartName) { 683 if (ProfilerLogManager.isInfoEnabled()) { 684 LOGGER.info("setSecondLevelTreeTable"); 685 } 686 agentHeapSplitter.setProportion(LayoutConstants.PROPORTION_SEGMENT); 687 // instance Table panel 688 JBPanel instanceView = new JBPanel(); 689 instanceView.setLayout(new BorderLayout()); 690 instanceView.setOpaque(true); 691 instanceView.setBackground(JBColor.background().darker()); 692 693 setTitleStyle(className, instanceView, 1); 694 695 instanceView.setPreferredSize(new Dimension(INSTANCE_TITLE_WIDTH, NUM_418)); 696 // Table header 697 Vector<String> columnNames = new Vector<>(); 698 columnNames.add("instance"); 699 columnNames.add("allocTime"); 700 columnNames.add("DealloTime"); 701 columnNames.add("InstanceId"); 702 // Display JBTable 703 DefaultTableModel defaultTableModel = new DefaultTableModel() { 704 /** 705 * isCellEditable 706 * 707 * @param row row 708 * @param column column 709 * @return boolean 710 */ 711 public boolean isCellEditable(int row, int column) { 712 return false; 713 } 714 }; 715 defaultTableModel.setColumnIdentifiers(columnNames); 716 instanceViewTable = new JBTable(defaultTableModel); 717 setExtracted(defaultTableModel, instanceViewTable); 718 // Initialize table data 719 initData(defaultTableModel, clazzId, className, sessionId, chartName); 720 JBScrollPane jScrollPane = new JBScrollPane(instanceViewTable); 721 jScrollPane.setPreferredSize(new Dimension(INSTANCE_TITLE_WIDTH, INSTANCE_PANE_HEIGHT)); 722 instanceView.add(jScrollPane, BorderLayout.CENTER); 723 return instanceView; 724 } 725 726 /** 727 * 初始化table 表格 728 * 729 * @param model model 730 * @param cId cId 731 * @param className className 732 * @param sessionId long 733 * @param chartName chartName 734 */ initData(DefaultTableModel model, Integer cId, String className, long sessionId, String chartName)735 public void initData(DefaultTableModel model, Integer cId, String className, long sessionId, String chartName) { 736 if (ProfilerLogManager.isInfoEnabled()) { 737 LOGGER.info("initData"); 738 } 739 MemoryInstanceManager memoryInstanceManager = new MemoryInstanceManager(); 740 ChartStandard standard = ProfilerChartsView.sessionMap.get(sessionId).getPublisher().getStandard(); 741 long firstTime = standard.getFirstTimestamp(); 742 ChartDataRange selectedRange = standard.getSelectedRange(chartName); 743 long endTime = selectedRange.getEndTime() + firstTime; 744 List<MemoryInstanceInfo> memoryInstanceInfos = memoryInstanceManager.getMemoryInstanceInfos(cId, 0L, endTime); 745 memoryInstanceInfos.forEach(memoryInstanceInfo -> { 746 long deallocTime = memoryInstanceInfo.getDeallocTime(); 747 long alloc = TimeUnit.MILLISECONDS.toMicros(memoryInstanceInfo.getAllocTime() - firstTime); 748 String allocTime = getSemiSimplifiedClockString(alloc); 749 String deAllocTime = " - "; 750 if (deallocTime != 0) { 751 long deAllocations = TimeUnit.MILLISECONDS.toMicros(memoryInstanceInfo.getDeallocTime() - firstTime); 752 deAllocTime = getSemiSimplifiedClockString(deAllocations); 753 } 754 Integer instanceId = memoryInstanceInfo.getInstanceId(); 755 Vector<Object> rowData = new Vector<>(); 756 rowData.add(className); 757 rowData.add(allocTime); 758 rowData.add(deAllocTime); 759 rowData.add(instanceId); 760 model.addRow(rowData); 761 }); 762 } 763 764 /** 765 * Return a formatted time String in the form of "hh:mm:ss.sss"". 766 * Hide hours value if both hours and minutes value are zero. 767 * Default format for Tooltips. 768 * 769 * @param micro micro 770 * @return String 771 */ getSemiSimplifiedClockString(long micro)772 public String getSemiSimplifiedClockString(long micro) { 773 if (ProfilerLogManager.isInfoEnabled()) { 774 LOGGER.info("getSemiSimplifiedClockString"); 775 } 776 long micros = Math.max(0, micro); 777 return getFullClockString(micros); 778 } 779 780 /** 781 * Return a formatted time String in the form of "hh:mm:ss.sss". 782 * Default format for Range description. 783 * 784 * @param micro micro 785 * @return String 786 */ getFullClockString(long micro)787 public String getFullClockString(long micro) { 788 if (ProfilerLogManager.isInfoEnabled()) { 789 LOGGER.info("getFullClockString"); 790 } 791 long micros = Math.max(0, micro); 792 long milli = TimeUnit.MICROSECONDS.toMillis(micros) % TimeUnit.SECONDS.toMillis(1); 793 long sec = TimeUnit.MICROSECONDS.toSeconds(micros) % TimeUnit.MINUTES.toSeconds(1); 794 long min = TimeUnit.MICROSECONDS.toMinutes(micros) % TimeUnit.HOURS.toMinutes(1); 795 long hour = TimeUnit.MICROSECONDS.toHours(micros); 796 return String.format(Locale.ENGLISH, "%02d:%02d:%02d.%03d", hour, min, sec, milli); 797 } 798 setExtracted(DefaultTableModel model, JBTable table)799 private void setExtracted(DefaultTableModel model, JBTable table) { 800 if (ProfilerLogManager.isInfoEnabled()) { 801 LOGGER.info("setExtracted"); 802 } 803 table.getTableHeader().setFont(new Font("PingFang SC", Font.PLAIN, LayoutConstants.FONT_SIZE)); 804 table.setFont(new Font("PingFang SC", Font.PLAIN, LayoutConstants.TWELVE)); 805 table.setOpaque(true); 806 table.setShowHorizontalLines(false); 807 table.getTableHeader().getColumnModel().getColumn(3).setMaxWidth(0); 808 table.getTableHeader().getColumnModel().getColumn(3).setMinWidth(0); 809 table.getTableHeader().getColumnModel().getColumn(3).setPreferredWidth(0); 810 RowSorter<TableModel> sorter = new TableRowSorter<>(model); 811 table.setRowSorter(sorter); 812 } 813 814 /** 815 * Three-level treeTable interface 816 * 817 * @param sessionId sessionId 818 * @param instanceId instanceId 819 * @param name name 820 * @return JBPanel 821 */ setThirdLevelTreeTable(long sessionId, int instanceId, String name)822 public JBPanel setThirdLevelTreeTable(long sessionId, int instanceId, String name) { 823 if (ProfilerLogManager.isInfoEnabled()) { 824 LOGGER.info("setThirdLevelTreeTable"); 825 } 826 agentHeapSplitter.setProportion(PROPORTION_SEGMENT_VIEW); 827 instanceAndDetailSplitter.setProportion(PROPORTION_SEGMENT_HEAP); 828 // Reserved Tree Table panel 829 JBPanel fieldsView = new JBPanel(new BorderLayout()); 830 fieldsView.setOpaque(true); 831 setTitleStyle(name, fieldsView, 0); 832 fieldsView.setPreferredSize(new Dimension(NUM_384, NUM_418)); 833 Vector<String> columnNames = new Vector<>(); 834 columnNames.add("Allocation Call Stack"); 835 DefaultTableModel model = new DefaultTableModel() { 836 /** 837 * Returns true regardless of parameter values. 838 * 839 * @param row the row whose value is to be queried 840 * @param column the column whose value is to be queried 841 * @return true 842 */ 843 @Override 844 public boolean isCellEditable(int row, int column) { 845 return false; 846 } 847 }; 848 model.setColumnIdentifiers(columnNames); 849 JBTable callStackTable = new JBTable(model); 850 DefaultTableCellRenderer defaultCellRender = new DefaultTableCellRenderer() { 851 @Override 852 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 853 boolean hasFocus, int row, int column) { 854 JLabel jLabel = null; 855 Object jLabelObject = 856 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 857 if (jLabelObject instanceof JLabel) { 858 jLabel = (JLabel) jLabelObject; 859 jLabel.setIcon(AllIcons.Nodes.Method); 860 } 861 return jLabel; 862 } 863 }; 864 defaultCellRender.getTableCellRendererComponent(callStackTable, null, false, false, 1, 0); 865 callStackTable.getColumnModel().getColumn(0).setCellRenderer(defaultCellRender); 866 MemoryInstanceDetailsManager detailsManager = new MemoryInstanceDetailsManager(); 867 ArrayList<MemoryInstanceDetailsInfo> detailsInfos = detailsManager.getMemoryInstanceDetailsInfos(instanceId); 868 detailsInfos.forEach(detailsInfo -> { 869 Vector<String> rowData = new Vector<>(); 870 rowData.add( 871 detailsInfo.getMethodName() + ":" + detailsInfo.getLineNumber() + "," + detailsInfo.getClassName() 872 + "; (" + detailsInfo.getFieldName() + ")"); 873 model.addRow(rowData); 874 }); 875 callStackTable.setShowHorizontalLines(false); 876 JBScrollPane jScrollPane = new JBScrollPane(callStackTable); 877 jScrollPane.setPreferredSize(new Dimension(INSTANCE_TITLE_WIDTH, INSTANCE_SCROLL_HEIGHT)); 878 fieldsView.add(jScrollPane, BorderLayout.CENTER); 879 return fieldsView; 880 } 881 setTitleStyle(String name, JBPanel viewStyle, int status)882 private void setTitleStyle(String name, JBPanel viewStyle, int status) { 883 if (ProfilerLogManager.isInfoEnabled()) { 884 LOGGER.info("setTitleStyle"); 885 } 886 JBLabel jbLabel = new JBLabel(); 887 if (status == 0) { 888 jbLabel.setText(" Instance Details-" + name); 889 } else { 890 jbLabel.setText(" Instance view"); 891 } 892 Font font = new Font("PingFang SC", Font.PLAIN, LayoutConstants.FONT_SIZE); 893 jbLabel.setFont(font); 894 JBLabel closeLabel = new JBLabel(AllIcons.Actions.Close); 895 closeLabel.addMouseListener(new MouseAdapter() { 896 @Override 897 public void mouseClicked(MouseEvent mouseEvent) { 898 super.mouseClicked(mouseEvent); 899 if (status == 0) { 900 instanceAndDetailSplitter.setSecondComponent(new JBSplitter(false, 1)); 901 } else { 902 agentHeapSplitter.setSecondComponent(new JBSplitter(false, 1)); 903 } 904 } 905 }); 906 907 JBPanel titlePanel = new JBPanel(new BorderLayout()); 908 titlePanel.setOpaque(true); 909 titlePanel.setBackground(JBColor.background().darker()); 910 titlePanel.setPreferredSize(new Dimension(NUM_384, INSTANCE_TITLE_HEIGHT)); 911 titlePanel.add(jbLabel, BorderLayout.WEST); 912 titlePanel.add(closeLabel, BorderLayout.EAST); 913 viewStyle.add(titlePanel, BorderLayout.NORTH); 914 } 915 chartRightMouseClick()916 private void chartRightMouseClick() { 917 if (heapViewPanel != null) { 918 this.remove(heapViewPanel); 919 heapViewPanel = null; 920 memoryTreeTablePanel = null; 921 } 922 } 923 chartMouseDragged()924 private void chartMouseDragged() { 925 if (ProfilerLogManager.isInfoEnabled()) { 926 LOGGER.info("chartMouseDragged"); 927 } 928 } 929 chartMouseRelease()930 private void chartMouseRelease() { 931 long sessionId = this.bottomPanel.getSessionId(); 932 SessionInfo sessionInfo = SessionManager.getInstance().getSessionInfo(sessionId); 933 if (!sessionInfo.isOfflineMode() 934 && sessionInfo.getDeviceIPPortInfo().getDeviceType() == DeviceType.LEAN_HOS_DEVICE) { 935 return; 936 } 937 refreshAgentHeapInfo(sessionId); 938 } 939 940 private class MemoryTitleView extends JBPanel { 941 /** 942 * Save the components should be hidden when item fold 943 */ 944 private JBPanel hiddenComp; 945 MemoryTitleView()946 MemoryTitleView() { 947 this.setLayout(new FlowLayout(FlowLayout.LEFT)); 948 initFixedComps(); 949 initHiddenComponents(); 950 this.setBackground(JBColor.background().brighter()); 951 } 952 initFixedComps()953 private void initFixedComps() { 954 if (ProfilerLogManager.isInfoEnabled()) { 955 LOGGER.info("initFixedComps"); 956 } 957 foldBtn = new JBLabel(); 958 foldBtn.setName(UtConstant.UT_MEMORY_ITEM_VIEW_FOLD); 959 foldBtn.setIcon(AllIcons.General.ArrowRight); 960 this.add(foldBtn); 961 foldBtn.addMouseListener(new MouseAdapter() { 962 @Override 963 public void mouseClicked(MouseEvent event) { 964 foldBtnClick(); 965 } 966 }); 967 JBLabel title = new JBLabel(item.getName()); 968 this.add(title); 969 } 970 foldBtnClick()971 private void foldBtnClick() { 972 if (ProfilerLogManager.isInfoEnabled()) { 973 LOGGER.info("foldBtnClick"); 974 } 975 fold = !fold; 976 // Item fold, buttons hide 977 hiddenComp.setVisible(!fold); 978 if (fold) { 979 chart.setFold(true); 980 chart.setEnableSelect(false); 981 chart.getTooltip().hideTip(); 982 foldBtn.setIcon(AllIcons.General.ArrowRight); 983 if (heapViewPanel != null) { 984 MemoryItemView.this.remove(heapViewPanel); 985 heapViewPanel = null; 986 } 987 if (memoryTreeTablePanel != null) { 988 MemoryItemView.this.remove(memoryTreeTablePanel); 989 memoryTreeTablePanel = null; 990 } 991 } else { 992 EventTrackUtils.getInstance().trackApplicationMemory(); 993 // Uncheck the box after re-expanding 994 bottomPanel.getPublisher().getStandard().clearSelectedRange(item.getName()); 995 chart.setFold(false); 996 chart.setEnableSelect(true); 997 foldBtn.setIcon(AllIcons.General.ArrowDown); 998 } 999 parent.itemFoldOrExpend(fold, MemoryItemView.this); 1000 // Initialize the maximum value of Y axis here, because it may change after fold/expand 1001 chart.initMaxUnitY(); 1002 chartObserver.setChartFold(fold); 1003 } 1004 initHiddenComponents()1005 private void initHiddenComponents() { 1006 if (ProfilerLogManager.isInfoEnabled()) { 1007 LOGGER.info("initHiddenComponents"); 1008 } 1009 hiddenComp = new JBPanel(new FlowLayout(FlowLayout.LEFT)); 1010 hiddenComp.setBackground(JBColor.background().brighter()); 1011 this.add(hiddenComp); 1012 // Add components 1013 hiddenComp.add(new DottedLine()); 1014 initDetailCfgBtn(); 1015 initHeapDumpBtn(); 1016 hiddenComp.add(new DottedLine()); 1017 initNativeBtn(); 1018 initNativeConfigBtn(); 1019 // The initial state is folded and hiddenComp needs to be hidden 1020 hiddenComp.setVisible(false); 1021 } 1022 initDetailCfgBtn()1023 private void initDetailCfgBtn() { 1024 if (ProfilerLogManager.isInfoEnabled()) { 1025 LOGGER.info("initDetailCfgBtn"); 1026 } 1027 detailCfgBtn = new JBLabel(IconLoader.getIcon("/images/icon_dataselection_normal.png", getClass())); 1028 detailCfgBtn.setName(UtConstant.UT_MEMORY_ITEM_VIEW_DETAIL); 1029 hiddenComp.add(detailCfgBtn); 1030 MemoryItemPopupMenu memoryPopupMenu = new MemoryItemPopupMenu(bottomPanel.getSessionId(), chartObserver); 1031 detailCfgBtn.addMouseListener(new MouseAdapter() { 1032 @Override 1033 public void mouseClicked(MouseEvent mouseEvent) { 1034 memoryPopupMenu.showMemoryItems(detailCfgBtn, mouseEvent); 1035 } 1036 }); 1037 } 1038 initHeapDumpBtn()1039 private void initHeapDumpBtn() { 1040 if (ProfilerLogManager.isInfoEnabled()) { 1041 LOGGER.info("initHeapDumpBtn"); 1042 } 1043 heapDumpBtn = new JBLabel(); 1044 heapDumpBtn.setName(UtConstant.UT_MEMORY_ITEM_VIEW_HEAP_DUMP); 1045 heapDumpBtn.setToolTipText("Memory heap dump"); 1046 Icon icon; 1047 // Add support for heap dump in specific processes 1048 DeviceIPPortInfo deviceInfoBySessionId = 1049 SessionManager.getInstance().getDeviceInfoBySessionId(bottomPanel.getSessionId()); 1050 ProcessInfo processInfo = 1051 SessionManager.getInstance().getSessionInfo(bottomPanel.getSessionId()).getProcessInfo(); 1052 boolean isDebuggerProcess = 1053 ProcessManager.getInstance().checkIsDebuggerProcess(deviceInfoBySessionId, processInfo); 1054 if (isDebuggerProcess) { 1055 icon = IconLoader.getIcon("/images/icon_heap_dump_normal.png", getClass()); 1056 heapDumpBtn.addMouseListener(new MouseAdapter() { 1057 @Override 1058 public void mouseClicked(MouseEvent mouseEvent) { 1059 super.mouseClicked(mouseEvent); 1060 EventTrackUtils.getInstance().trackApplicationHprof(); 1061 int showTime = bottomPanel.getTimeline().getEndTime(); 1062 Date date = new Date(); 1063 StringWriter stringWriter = new StringWriter(); 1064 PrintWriter printWriter = new PrintWriter(stringWriter); 1065 date.setTime(showTime); 1066 printWriter.format("%1$tM:%1$tS.%tL", date); 1067 printWriter.flush(); 1068 bottomPanel.getTaskScenePanelChart() 1069 .createSessionList(LayoutConstants.HEAP_DUMP, stringWriter.toString(), 1070 bottomPanel.getSessionId(), null); 1071 } 1072 }); 1073 } else { 1074 icon = IconLoader.getIcon("/images/icon_heap_dump_grey.png", getClass()); 1075 } 1076 heapDumpBtn.setIcon(icon); 1077 hiddenComp.add(heapDumpBtn); 1078 } 1079 initNativeBtn()1080 private void initNativeBtn() { 1081 if (ProfilerLogManager.isInfoEnabled()) { 1082 LOGGER.info("initNativeBtn"); 1083 } 1084 nativeBtn = new JButton(" Record native allocations "); 1085 DeviceType deviceType = SessionManager.getInstance().getDeviceType(bottomPanel.getSessionId()); 1086 if (deviceType == DeviceType.FULL_HOS_DEVICE) { 1087 nativeBtn.setEnabled(false); 1088 nativeBtn.setBackground(JBColor.background().brighter()); 1089 } else { 1090 nativeBtn.setEnabled(true); 1091 nativeBtn.setName("nativeBtn"); 1092 nativeBtn.setOpaque(false); 1093 nativeBtn.addMouseListener(new MouseAdapter() { 1094 @Override 1095 public void mouseClicked(MouseEvent mouseEvent) { 1096 super.mouseClicked(mouseEvent); 1097 long sessionId = bottomPanel.getSessionId(); 1098 SessionInfo sessionInfo = SessionManager.getInstance().getSessionInfo(sessionId); 1099 if (Objects.nonNull(sessionInfo)) { 1100 DeviceIPPortInfo deviceIPPortInfo = sessionInfo.getDeviceIPPortInfo(); 1101 ProcessInfo processInfo = new ProcessInfo(); 1102 processInfo.setProcessId(sessionInfo.getPid()); 1103 processInfo.setProcessName(sessionInfo.getProcessName()); 1104 long sessionOperationId = SessionManager.getInstance() 1105 .createSessionOperationStart(deviceIPPortInfo, processInfo, NATIVE_HOOK_PLUGIN_NAME); 1106 if (sessionOperationId != Constant.ABNORMAL) { 1107 sessionInfo.setSecondSessionId(sessionOperationId); 1108 bottomPanel.getTaskScenePanelChart().getjButtonStop() 1109 .setIcon(AllIcons.Process.ProgressResumeHover); 1110 bottomPanel.getTaskScenePanelChart().getjButtonStop().setToolTipText("Start"); 1111 bottomPanel.getPublisher().pauseRefresh(); 1112 bottomPanel.setPause(true); 1113 new NativeRecordDialog(bottomPanel, sessionId); 1114 } else { 1115 JPanel promptMessage = new JPanel(new BorderLayout()); 1116 JBLabel messageLabel = new JBLabel("Create Session Failed"); 1117 messageLabel.setPreferredSize(new Dimension(100, 70)); 1118 promptMessage.add(messageLabel, BorderLayout.CENTER); 1119 new CustomDialog("prompt", promptMessage).show(); 1120 } 1121 } 1122 } 1123 }); 1124 nativeBtn.setBorder(BorderFactory.createEmptyBorder()); 1125 } 1126 hiddenComp.add(nativeBtn); 1127 } 1128 1129 /** 1130 * init Native ConfigBtn 1131 */ initNativeConfigBtn()1132 private void initNativeConfigBtn() { 1133 JBLabel configButton = new JBLabel(); 1134 configButton.setIcon(IconLoader.getIcon("/images/icon_cpu_perfConfig.png", CpuItemView.class)); 1135 configButton.setOpaque(false); 1136 configButton.addMouseListener(new MouseAdapter() { 1137 @Override 1138 public void mouseClicked(MouseEvent event) { 1139 new NativeConfigDialog(); 1140 } 1141 }); 1142 hiddenComp.add(configButton); 1143 } 1144 } 1145 getHeapViewPanel()1146 public JBPanel getHeapViewPanel() { 1147 return heapViewPanel; 1148 } 1149 } 1150