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; 17 18 import com.intellij.ui.JBColor; 19 import com.intellij.ui.components.JBLabel; 20 import com.intellij.ui.components.JBPanel; 21 import com.intellij.ui.components.JBScrollPane; 22 import net.miginfocom.swing.MigLayout; 23 import ohos.devtools.datasources.utils.device.entity.DeviceIPPortInfo; 24 import ohos.devtools.datasources.utils.device.service.MultiDeviceManager; 25 import ohos.devtools.datasources.utils.process.entity.ProcessInfo; 26 import ohos.devtools.datasources.utils.process.service.ProcessManager; 27 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager; 28 import ohos.devtools.datasources.utils.quartzmanager.QuartzManager; 29 import ohos.devtools.services.distribute.DistributeDevice; 30 import ohos.devtools.services.distribute.DistributedManager; 31 import ohos.devtools.views.common.LayoutConstants; 32 import ohos.devtools.views.common.customcomp.SelectedTextFileLister; 33 import ohos.devtools.views.layout.dialog.SampleDialog; 34 import ohos.devtools.views.layout.dialog.TraceRecordDialog; 35 import ohos.devtools.views.layout.utils.EventTrackUtils; 36 import org.apache.commons.lang.StringUtils; 37 import org.apache.logging.log4j.LogManager; 38 import org.apache.logging.log4j.Logger; 39 40 import javax.swing.JButton; 41 import javax.swing.JSeparator; 42 import javax.swing.SwingUtilities; 43 import javax.swing.SwingWorker; 44 import java.awt.Dimension; 45 import java.awt.Font; 46 import java.awt.event.ItemEvent; 47 import java.awt.event.ItemListener; 48 import java.awt.event.MouseAdapter; 49 import java.awt.event.MouseEvent; 50 import java.util.ArrayList; 51 import java.util.Iterator; 52 import java.util.List; 53 import java.util.Objects; 54 import java.util.Vector; 55 import java.util.concurrent.ExecutionException; 56 57 import static ohos.devtools.views.common.Constant.DISTRIBUTED_REFRESH; 58 59 /** 60 * DistributedConfigPanel 61 * 62 * @since : 2021/10/25 63 */ 64 public class DistributedConfigPanel extends JBPanel { 65 private static final Logger LOGGER = LogManager.getLogger(DistributedConfigPanel.class); 66 private static final String LAST_STEP_BTN = "Last Step"; 67 private static final String START_TASK_BTN = "Start Task"; 68 69 private DistributedDeviceProcessPanel firstDevice; 70 private DistributedDeviceProcessPanel secondDevice; 71 private JBPanel buttonPanel; 72 private JButton lastStepBtn; 73 private JButton startTaskBtn; 74 private TaskPanel contentPanel; 75 76 /** 77 * DistributedConfigPanel constructor 78 * 79 * @param taskPanel taskPanel 80 */ DistributedConfigPanel(TaskPanel taskPanel)81 public DistributedConfigPanel(TaskPanel taskPanel) { 82 EventTrackUtils.getInstance().trackDistributedConfig(); 83 contentPanel = taskPanel; 84 this.setLayout(new MigLayout("inset 0", "15[grow,fill]", "15[fill,fill]")); 85 this.setOpaque(true); 86 this.setBackground(JBColor.background().darker()); 87 initComponents(); 88 addEventListener(); 89 } 90 91 /** 92 * initComponents 93 */ initComponents()94 private void initComponents() { 95 initDeviceDescriptionPage(); 96 initDevicePanel(); 97 initButtonPanel(); 98 } 99 100 /** 101 * initDeviceDescriptionPage 102 */ initDeviceDescriptionPage()103 private void initDeviceDescriptionPage() { 104 if (ProfilerLogManager.isInfoEnabled()) { 105 LOGGER.info("initDeviceDescriptionPage"); 106 } 107 JBPanel deviceDescription = new JBPanel(new MigLayout("insets 10", "[]20[]push")); 108 deviceDescription.setBackground(JBColor.background().darker()); 109 JBLabel deviceLabel = new JBLabel("Devices"); 110 deviceLabel.setOpaque(false); 111 deviceLabel.setFont(new Font("PingFang SC", Font.PLAIN, 24)); 112 deviceLabel.setForeground(JBColor.foreground().brighter()); 113 JBLabel deviceDescriptionLabel = new JBLabel("Task scene: Distribute tuning"); 114 deviceDescriptionLabel.setOpaque(false); 115 deviceDescriptionLabel.setFont(new Font("PingFang SC", Font.PLAIN, 14)); 116 deviceDescription.add(deviceLabel); 117 deviceDescription.add(deviceDescriptionLabel); 118 this.add(deviceDescription, "wrap"); 119 } 120 121 /** 122 * initDevicePanel 123 */ initDevicePanel()124 private void initDevicePanel() { 125 if (ProfilerLogManager.isInfoEnabled()) { 126 LOGGER.info("initDevicePanel"); 127 } 128 JBPanel devicePanel = new JBPanel(new MigLayout("insets 0", "[grow,fill]")); 129 firstDevice = new DistributedDeviceProcessPanel(1, true); 130 devicePanel.add(firstDevice, "wrap"); 131 devicePanel.add(new JSeparator(), "wrap"); 132 secondDevice = new DistributedDeviceProcessPanel(2, true); 133 devicePanel.add(secondDevice, "wrap"); 134 devicePanel.add(new JSeparator(), "wrap"); 135 JBScrollPane scrollPane = new JBScrollPane(devicePanel); 136 this.add(scrollPane, "wrap"); 137 } 138 139 /** 140 * initButtonPanel 141 */ initButtonPanel()142 private void initButtonPanel() { 143 if (ProfilerLogManager.isInfoEnabled()) { 144 LOGGER.info("initButtonPanel"); 145 } 146 buttonPanel = new JBPanel(new MigLayout("insets 0", "push[]20[]20", "20[fill,fill]")); 147 buttonPanel.setOpaque(false); 148 lastStepBtn = new JButton(LAST_STEP_BTN); 149 lastStepBtn.setName(LAST_STEP_BTN); 150 lastStepBtn.setFocusPainted(false); 151 lastStepBtn.setOpaque(false); 152 lastStepBtn.setPreferredSize(new Dimension(140, 40)); 153 startTaskBtn = new JButton(START_TASK_BTN); 154 startTaskBtn.setName(START_TASK_BTN); 155 startTaskBtn.setFocusPainted(false); 156 startTaskBtn.setOpaque(false); 157 startTaskBtn.setPreferredSize(new Dimension(140, 40)); 158 buttonPanel.add(lastStepBtn); 159 buttonPanel.add(startTaskBtn); 160 this.add(buttonPanel, "wrap, span"); 161 } 162 163 /** 164 * addEventListener 165 */ addEventListener()166 private void addEventListener() { 167 addRefreshDeviceList(); 168 addLastStepListener(); 169 addStartTaskListener(); 170 addFirstDeviceListener(); 171 addSecondDeviceListener(); 172 } 173 174 /** 175 * addLastStepListener 176 */ addLastStepListener()177 private void addLastStepListener() { 178 lastStepBtn.addMouseListener(new MouseAdapter() { 179 @Override 180 public void mouseClicked(MouseEvent mouseEvent) { 181 contentPanel.getTabContainer().remove(DistributedConfigPanel.this); 182 contentPanel.getTabItem().setVisible(true); 183 contentPanel.getTabContainer().repaint(); 184 QuartzManager.getInstance().deleteExecutor(DISTRIBUTED_REFRESH); 185 } 186 }); 187 } 188 189 /** 190 * addStartTaskListener 191 */ addStartTaskListener()192 private void addStartTaskListener() { 193 startTaskBtn.addMouseListener(new MouseAdapter() { 194 @Override 195 public void mouseClicked(MouseEvent mouseEvent) { 196 DeviceIPPortInfo item = firstDevice.getDeviceComboBox().getItem(); 197 DeviceIPPortInfo deviceIPPortInfo = secondDevice.getDeviceComboBox().getItem(); 198 if (Objects.isNull(item) || Objects.isNull(deviceIPPortInfo)) { 199 new SampleDialog("prompt", "Device list is empty !").show(); 200 return; 201 } 202 if (StringUtils.equals(item.getDeviceID(), deviceIPPortInfo.getDeviceID())) { 203 new SampleDialog("prompt", "The selection devices cannot be the same !").show(); 204 return; 205 } 206 String firstProcess = firstDevice.getSearchComBox().getSelectedProcessName(); 207 String secondProcess = secondDevice.getSearchComBox().getSelectedProcessName(); 208 if (StringUtils.isBlank(firstProcess) || StringUtils.isBlank(secondProcess)) { 209 new SampleDialog("prompt", "The selection process cannot be empty !").show(); 210 return; 211 } 212 DistributeDevice firstDeviceInfo = new DistributeDevice(item, firstProcess); 213 DistributeDevice secondDeviceInfo = new DistributeDevice(deviceIPPortInfo, secondProcess); 214 DistributedManager distributedManager = new DistributedManager(firstDeviceInfo, secondDeviceInfo); 215 boolean collectSuccess = distributedManager.startCollecting(); 216 if (collectSuccess) { 217 new TraceRecordDialog().load(contentPanel, distributedManager, true); 218 } else { 219 new SampleDialog("prompt", "Collection failed, please wait 10s then try again !").show(); 220 } 221 } 222 }); 223 } 224 225 /** 226 * addSecondDeviceListener 227 */ addSecondDeviceListener()228 private void addSecondDeviceListener() { 229 if (secondDevice != null) { 230 secondDevice.getSearchComBox().setSelectedTextFileListener(new SelectedTextFileLister() { 231 @Override 232 public void textFileClick() { 233 DeviceIPPortInfo item = secondDevice.getDeviceComboBox().getItem(); 234 ProcessManager instance = ProcessManager.getInstance(); 235 if (!instance.isRequestProcess()) { 236 new SwingWorker<List<String>, Integer>() { 237 @Override 238 protected List<String> doInBackground() { 239 secondDevice.getSearchComBox().getSelectedProcessTextFiled().setText(""); 240 LOGGER.info("start Process"); 241 List<ProcessInfo> processInfos = ProcessManager.getInstance().getProcessList(item); 242 LOGGER.info("Process end"); 243 List<String> processNames = new ArrayList<>(); 244 for (int index = 0; index < processInfos.size(); index++) { 245 ProcessInfo processInfo = processInfos.get(index); 246 processNames 247 .add(processInfo.getProcessName() + "(" + processInfo.getProcessId() + ")"); 248 } 249 LOGGER.info("processNames handle end"); 250 return processNames; 251 } 252 253 @Override 254 protected void done() { 255 try { 256 LOGGER.info("getVector"); 257 List<String> vector = get(); 258 LOGGER.info("getVector end"); 259 secondDevice.getSearchComBox().refreshProcess(vector); 260 LOGGER.info(" refreshProcess end"); 261 } catch (InterruptedException | ExecutionException exception) { 262 exception.printStackTrace(); 263 } finally { 264 ProcessManager.getInstance().setIsRequest(false); 265 } 266 } 267 }.execute(); 268 } 269 } 270 }); 271 secondDevice.getDeviceComboBox().addItemListener(new ItemListener() { 272 @Override 273 public void itemStateChanged(ItemEvent itemEvent) { 274 secondDevice.getSearchComBox().clearSelectedName(); 275 } 276 }); 277 } 278 } 279 280 /** 281 * addFirstDeviceListener 282 */ addFirstDeviceListener()283 private void addFirstDeviceListener() { 284 if (firstDevice != null) { 285 firstDevice.getSearchComBox().setSelectedTextFileListener(new SelectedTextFileLister() { 286 @Override 287 public void textFileClick() { 288 DeviceIPPortInfo item = firstDevice.getDeviceComboBox().getItem(); 289 ProcessManager instance = ProcessManager.getInstance(); 290 if (!instance.isRequestProcess()) { 291 new SwingWorker<List<String>, Integer>() { 292 @Override 293 protected List<String> doInBackground() { 294 firstDevice.getSearchComBox().getSelectedProcessTextFiled().setText(""); 295 List<ProcessInfo> processInfos = ProcessManager.getInstance().getProcessList(item); 296 List<String> processNames = new ArrayList<>(); 297 for (int index = 0; index < processInfos.size(); index++) { 298 ProcessInfo processInfo = processInfos.get(index); 299 processNames 300 .add(processInfo.getProcessName() + "(" + processInfo.getProcessId() + ")"); 301 } 302 return processNames; 303 } 304 305 @Override 306 protected void done() { 307 try { 308 List<String> vector = get(); 309 firstDevice.getSearchComBox().refreshProcess(vector); 310 } catch (InterruptedException | ExecutionException exception) { 311 exception.printStackTrace(); 312 } finally { 313 ProcessManager.getInstance().setIsRequest(false); 314 } 315 } 316 }.execute(); 317 } 318 } 319 }); 320 firstDevice.getDeviceComboBox().addItemListener(new ItemListener() { 321 @Override 322 public void itemStateChanged(ItemEvent itemEvent) { 323 firstDevice.getSearchComBox().clearSelectedName(); 324 } 325 }); 326 } 327 } 328 329 /** 330 * addRefreshDeviceList 331 */ addRefreshDeviceList()332 private void addRefreshDeviceList() { 333 QuartzManager.getInstance().addExecutor(DISTRIBUTED_REFRESH, new Runnable() { 334 @Override 335 public void run() { 336 List<DeviceIPPortInfo> deviceInfos = MultiDeviceManager.getInstance().getOnlineDeviceInfoList(); 337 if (!deviceInfos.isEmpty()) { 338 Vector<DeviceIPPortInfo> items = new Vector<DeviceIPPortInfo>(); 339 for (DeviceIPPortInfo deviceIPPortInfo : deviceInfos) { 340 items.add(deviceIPPortInfo); 341 } 342 Vector<DeviceIPPortInfo> oldDevice = firstDevice.getVector(); 343 if (!compareVector(oldDevice, items)) { 344 SwingUtilities.invokeLater(new Runnable() { 345 @Override 346 public void run() { 347 firstDevice.refreshDeviceItem(items); 348 secondDevice.refreshDeviceItem(vectorReverse(items)); 349 } 350 }); 351 } 352 } else { 353 SwingUtilities.invokeLater(new Runnable() { 354 @Override 355 public void run() { 356 Vector<DeviceIPPortInfo> items = new Vector<>(); 357 firstDevice.refreshDeviceItem(items); 358 secondDevice.refreshDeviceItem(items); 359 firstDevice.getSearchComBox().clearSelectedName(); 360 secondDevice.getSearchComBox().clearSelectedName(); 361 } 362 }); 363 } 364 } 365 }); 366 QuartzManager.getInstance().startExecutor(DISTRIBUTED_REFRESH, 0, LayoutConstants.THOUSAND); 367 } 368 369 /** 370 * vectorReverse 371 * 372 * @param vector oldVector 373 * @return new vector 374 */ vectorReverse(Vector<DeviceIPPortInfo> vector)375 private Vector<DeviceIPPortInfo> vectorReverse(Vector<DeviceIPPortInfo> vector) { 376 Vector<DeviceIPPortInfo> deviceIPPortInfos = new Vector<>(); 377 for (int index = (vector.size() - 1); index >= 0; index--) { 378 DeviceIPPortInfo deviceIPPortInfo = vector.get(index); 379 deviceIPPortInfos.add(deviceIPPortInfo); 380 } 381 return deviceIPPortInfos; 382 } 383 384 /** 385 * compareVector 386 * 387 * @param first first 388 * @param second second 389 * @return boolean 390 */ compareVector(Vector<DeviceIPPortInfo> first, Vector<DeviceIPPortInfo> second)391 private boolean compareVector(Vector<DeviceIPPortInfo> first, Vector<DeviceIPPortInfo> second) { 392 if (Objects.isNull(first) && Objects.isNull(second)) { 393 return true; 394 } 395 if (Objects.isNull(first) || Objects.isNull(second)) { 396 return false; 397 } 398 if (first.size() == second.size()) { 399 return compareWithVector(first, second); 400 } else { 401 return false; 402 } 403 } 404 405 /** 406 * compareWithVector 407 * 408 * @param oldVector oldVector 409 * @param newVector newVector 410 * @return boolean 411 */ compareWithVector(Vector<DeviceIPPortInfo> oldVector, Vector<DeviceIPPortInfo> newVector)412 private boolean compareWithVector(Vector<DeviceIPPortInfo> oldVector, Vector<DeviceIPPortInfo> newVector) { 413 StringBuilder builder = new StringBuilder(); 414 Iterator<DeviceIPPortInfo> iterator = oldVector.iterator(); 415 while (iterator.hasNext()) { 416 DeviceIPPortInfo deviceIPPortInfo = iterator.next(); 417 builder.append(deviceIPPortInfo.getDeviceName()).append("_").append(deviceIPPortInfo.getDeviceID()); 418 } 419 int count = 0; 420 String firstString = builder.toString(); 421 Iterator<DeviceIPPortInfo> newIterator = newVector.iterator(); 422 while (newIterator.hasNext()) { 423 DeviceIPPortInfo deviceIPPortInfo = newIterator.next(); 424 String map1KeyVal = deviceIPPortInfo.getDeviceName() + "_" + deviceIPPortInfo.getDeviceID(); 425 boolean contains = firstString.contains(map1KeyVal); 426 if (contains) { 427 count++; 428 } 429 } 430 if (newVector.size() == count) { 431 return true; 432 } else { 433 return false; 434 } 435 } 436 } 437