Startup Frame should scan for available hardware fix #4633
This commit is contained in:
parent
50344d32df
commit
771b907156
|
@ -2,11 +2,11 @@ package com.rusefi;
|
|||
|
||||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.io.tcp.TcpConnector;
|
||||
import com.rusefi.maintenance.DfuFlasher;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static com.rusefi.FileLog.isLinux;
|
||||
|
@ -23,54 +23,66 @@ public enum SerialPortScanner {
|
|||
private static final boolean SHOW_SOCKETCAN = isLinux();
|
||||
|
||||
static final String AUTO_SERIAL = "Auto Serial";
|
||||
@NotNull
|
||||
private final List<String> knownPorts = new ArrayList<>();
|
||||
|
||||
public List<Listener> listeners = new CopyOnWriteArrayList<>();
|
||||
private final Object lock = new Object();
|
||||
@NotNull
|
||||
private AvailableHardware knownHardware = new AvailableHardware(Collections.emptyList(), false, false);
|
||||
|
||||
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
public void addListener(Listener listener) {
|
||||
boolean shouldStart = listeners.isEmpty();
|
||||
listeners.add(listener);
|
||||
if (shouldStart)
|
||||
startTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all available serial ports and checks if simulator local TCP port is available
|
||||
*/
|
||||
private void findAllAvailablePorts(boolean includeSlowTcpLookup) {
|
||||
List<String> ports = new ArrayList<>();
|
||||
boolean dfuConnected;
|
||||
boolean stLinkConnected;
|
||||
|
||||
String[] serialPorts = LinkManager.getCommPorts();
|
||||
if (serialPorts.length > 0)
|
||||
ports.add(AUTO_SERIAL);
|
||||
ports.addAll(Arrays.asList(serialPorts));
|
||||
if (includeSlowTcpLookup)
|
||||
|
||||
if (includeSlowTcpLookup) {
|
||||
ports.addAll(TcpConnector.getAvailablePorts());
|
||||
dfuConnected = DfuFlasher.detectSTM32BootloaderDriverState(StatusConsumer.VOID);
|
||||
stLinkConnected = DfuFlasher.detectStLink(StatusConsumer.VOID);
|
||||
} else {
|
||||
dfuConnected = false;
|
||||
stLinkConnected = false;
|
||||
}
|
||||
if (SHOW_PCAN)
|
||||
ports.add(LinkManager.PCAN);
|
||||
if (SHOW_SOCKETCAN)
|
||||
ports.add(LinkManager.SOCKET_CAN);
|
||||
|
||||
boolean isListUpdated;
|
||||
synchronized (knownPorts) {
|
||||
isListUpdated = knownPorts.equals(ports);
|
||||
knownPorts.clear();
|
||||
knownPorts.addAll(ports);
|
||||
AvailableHardware currentHardware = new AvailableHardware(ports, dfuConnected, stLinkConnected);
|
||||
synchronized (lock) {
|
||||
isListUpdated = !knownHardware.equals(currentHardware);
|
||||
knownHardware = currentHardware;
|
||||
}
|
||||
if (isListUpdated) {
|
||||
for (Listener listener : listeners)
|
||||
listener.onChange();
|
||||
listener.onChange(currentHardware);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getKnownPorts() {
|
||||
synchronized (knownPorts) {
|
||||
return new ArrayList<>(knownPorts);
|
||||
}
|
||||
}
|
||||
|
||||
public void startTimer() {
|
||||
private void startTimer() {
|
||||
Thread portsScanner = new Thread(() -> {
|
||||
boolean isFirstTime = true;
|
||||
while (isRunning) {
|
||||
findAllAvailablePorts(!isFirstTime);
|
||||
isFirstTime = false;
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(300);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
@ -86,6 +98,44 @@ public enum SerialPortScanner {
|
|||
}
|
||||
|
||||
interface Listener {
|
||||
void onChange();
|
||||
void onChange(AvailableHardware currentHardware);
|
||||
}
|
||||
|
||||
public static class AvailableHardware {
|
||||
|
||||
private final List<String> ports;
|
||||
private final boolean dfuFound;
|
||||
private final boolean stLinkConnected;
|
||||
|
||||
public <T> AvailableHardware(List<String> ports, boolean dfuFound, boolean stLinkConnected) {
|
||||
this.ports = ports;
|
||||
this.dfuFound = dfuFound;
|
||||
this.stLinkConnected = stLinkConnected;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getKnownPorts() {
|
||||
return new ArrayList<>(ports);
|
||||
}
|
||||
|
||||
public boolean isDfuFound() {
|
||||
return dfuFound;
|
||||
}
|
||||
|
||||
public boolean isStLinkConnected() {
|
||||
return stLinkConnected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AvailableHardware that = (AvailableHardware) o;
|
||||
return dfuFound == that.dfuFound && stLinkConnected == that.stLinkConnected && ports.equals(that.ports);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return !dfuFound && !stLinkConnected && ports.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,9 +57,6 @@ public class StartupFrame {
|
|||
private final JPanel connectPanel = new JPanel(new FlowLayout());
|
||||
// todo: move this line to the connectPanel
|
||||
private final JComboBox<String> comboPorts = new JComboBox<>();
|
||||
@NotNull
|
||||
private List<String> currentlyDisplayedPorts = new ArrayList<>();
|
||||
private boolean isFirstTimeApplyingPorts = true;
|
||||
private final JPanel leftPanel = new JPanel(new VerticalFlowLayout());
|
||||
|
||||
private final JPanel realHardwarePanel = new JPanel(new MigLayout());
|
||||
|
@ -93,7 +90,6 @@ public class StartupFrame {
|
|||
}
|
||||
});
|
||||
AutoupdateUtil.setAppIcon(frame);
|
||||
SerialPortScanner.INSTANCE.startTimer();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -122,6 +118,7 @@ public class StartupFrame {
|
|||
//connectButton.setBackground(new Color(RUSEFI_ORANGE)); // custom orange
|
||||
setToolTip(connectButton, "Connect to real hardware");
|
||||
connectPanel.add(connectButton);
|
||||
connectPanel.setVisible(false);
|
||||
|
||||
frame.getRootPane().setDefaultButton(connectButton);
|
||||
connectButton.addKeyListener(new KeyAdapter() {
|
||||
|
@ -149,10 +146,11 @@ public class StartupFrame {
|
|||
realHardwarePanel.add(noPortsMessage, "right, wrap");
|
||||
installMessage(noPortsMessage, "Check you cables. Check your drivers. Do you want to start simulator maybe?");
|
||||
|
||||
ProgramSelector selector = new ProgramSelector(comboPorts);
|
||||
|
||||
if (FileLog.isWindows()) {
|
||||
realHardwarePanel.add(new HorizontalLine(), "right, wrap");
|
||||
|
||||
ProgramSelector selector = new ProgramSelector(comboPorts);
|
||||
realHardwarePanel.add(selector.getControl(), "right, wrap");
|
||||
|
||||
// for F7 builds we just build one file at the moment
|
||||
|
@ -170,7 +168,11 @@ public class StartupFrame {
|
|||
//realHardwarePanel.add(new EraseChip().getButton(), "right, wrap");
|
||||
}
|
||||
|
||||
SerialPortScanner.INSTANCE.listeners.add(() -> SwingUtilities.invokeLater(this::applyKnownPorts));
|
||||
SerialPortScanner.INSTANCE.addListener(currentHardware -> SwingUtilities.invokeLater(() -> {
|
||||
selector.apply(currentHardware);
|
||||
applyKnownPorts(currentHardware);
|
||||
frame.pack();
|
||||
}));
|
||||
|
||||
final JButton buttonLogViewer = new JButton();
|
||||
buttonLogViewer.setText("Start " + LinkManager.LOG_VIEWER);
|
||||
|
@ -226,19 +228,14 @@ public class StartupFrame {
|
|||
}
|
||||
}
|
||||
|
||||
private void applyKnownPorts() {
|
||||
List<String> ports = SerialPortScanner.INSTANCE.getKnownPorts();
|
||||
if (!currentlyDisplayedPorts.equals(ports) || isFirstTimeApplyingPorts) {
|
||||
private void applyKnownPorts(SerialPortScanner.AvailableHardware currentHardware) {
|
||||
List<String> ports = currentHardware.getKnownPorts();
|
||||
log.info("Rendering available ports: " + ports);
|
||||
isFirstTimeApplyingPorts = false;
|
||||
connectPanel.setVisible(!ports.isEmpty());
|
||||
noPortsMessage.setVisible(ports.isEmpty());
|
||||
|
||||
applyPortSelectionToUIcontrol(ports);
|
||||
currentlyDisplayedPorts = ports;
|
||||
UiUtils.trueLayout(connectPanel);
|
||||
frame.pack();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFrameIcon(Frame frame) {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package com.rusefi.maintenance;
|
||||
|
||||
import com.rusefi.Launcher;
|
||||
import com.rusefi.SerialPortScanner;
|
||||
import com.rusefi.autodetect.PortDetector;
|
||||
import com.rusefi.autoupdate.AutoupdateUtil;
|
||||
import com.rusefi.ui.StatusWindow;
|
||||
import com.rusefi.ui.util.URLLabel;
|
||||
import com.rusefi.ui.util.UiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -17,6 +19,7 @@ import java.util.Objects;
|
|||
|
||||
import static com.rusefi.StartupFrame.appendBundleName;
|
||||
import static com.rusefi.ui.storage.PersistentConfiguration.getConfig;
|
||||
import static com.rusefi.ui.util.UiUtils.trueLayout;
|
||||
|
||||
public class ProgramSelector {
|
||||
|
||||
|
@ -33,22 +36,16 @@ public class ProgramSelector {
|
|||
public static final String BOOT_COMMANDER_EXE = "BootCommander.exe";
|
||||
public static final String OPENBLT_BINARY_LOCATION = Launcher.TOOLS_PATH + File.separator + "openblt";
|
||||
|
||||
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
private final JLabel noHardware = new JLabel("Nothing detected");
|
||||
private final JPanel controls = new JPanel(new FlowLayout());
|
||||
private final JComboBox<String> mode = new JComboBox<>();
|
||||
|
||||
public ProgramSelector(JComboBox<String> comboPorts) {
|
||||
/*
|
||||
* todo: add FULL AUTO mode which would fire up DFU and ST-LINK in parallel hoping that one of those would work?
|
||||
*/
|
||||
if (IS_WIN) {
|
||||
mode.addItem(AUTO_DFU);
|
||||
mode.addItem(MANUAL_DFU);
|
||||
mode.addItem(DFU_ERASE);
|
||||
mode.addItem(ST_LINK);
|
||||
mode.addItem(OPENBLT_CAN);
|
||||
}
|
||||
mode.addItem(DFU_SWITCH);
|
||||
|
||||
content.add(controls, BorderLayout.NORTH);
|
||||
content.add(noHardware, BorderLayout.SOUTH);
|
||||
controls.setVisible(false);
|
||||
controls.add(mode);
|
||||
|
||||
String persistedMode = getConfig().getRoot().getProperty(getClass().getSimpleName());
|
||||
|
@ -117,6 +114,28 @@ public class ProgramSelector {
|
|||
}
|
||||
|
||||
public JPanel getControl() {
|
||||
return controls;
|
||||
return content;
|
||||
}
|
||||
|
||||
public void apply(SerialPortScanner.AvailableHardware currentHardware) {
|
||||
noHardware.setVisible(currentHardware.isEmpty());
|
||||
controls.setVisible(!currentHardware.isEmpty());
|
||||
|
||||
mode.removeAllItems();
|
||||
if (IS_WIN) {
|
||||
if (!currentHardware.getKnownPorts().isEmpty())
|
||||
mode.addItem(AUTO_DFU);
|
||||
if (currentHardware.isDfuFound()) {
|
||||
mode.addItem(MANUAL_DFU);
|
||||
mode.addItem(DFU_ERASE);
|
||||
}
|
||||
if (currentHardware.isStLinkConnected())
|
||||
mode.addItem(ST_LINK);
|
||||
// todo: detect PCAN mode.addItem(OPENBLT_CAN);
|
||||
}
|
||||
if (!currentHardware.getKnownPorts().isEmpty())
|
||||
mode.addItem(DFU_SWITCH);
|
||||
trueLayout(mode);
|
||||
UiUtils.trueLayout(content);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue