From: Keith Packard Date: Thu, 23 Aug 2018 00:44:02 +0000 (-0700) Subject: altosuilib: Provide dialog while waiting for flash target to re-appear X-Git-Tag: 1.8.7~3^2~52 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=87ae17f888b745de71790d071846b96ab96e1529 altosuilib: Provide dialog while waiting for flash target to re-appear On windows, switching to the boot loader can take a long time. Instead of timing out after a second, show a dialog and let the user cancel the operation if they get bored of waiting. Signed-off-by: Keith Packard --- diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 4d9c662c..6c9cae52 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -346,7 +346,7 @@ public class AltosFlashUI device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); - } else if (e instanceof IOException) { + } else { JOptionPane.showMessageDialog(frame, e.getMessage(), file.toString(), @@ -429,45 +429,235 @@ public class AltosFlashUI flash_task flasher; - private boolean open_device() throws InterruptedException { - try { - link = new AltosSerial(device); - if (is_pair_programmed()) - return true; - if (link == null) - throw new IOException(String.format("%s: open failed", device.toShortString())); + class open_task implements Runnable { + AltosDevice device; + Thread t; + open_dialog dialog; - while (!link.is_loader()) { - link.to_loader(); + public void do_exception(final Exception e) { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_exception(e); } catch (Exception ex) { } + } + }); + } - java.util.List devices = null; + public void do_success(final AltosLink link) { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_success(link); } catch (Exception ex) { } + } + }); + } - for (int tries = 0; tries < 10; tries++) { - Thread.sleep(100); - devices = AltosUSBDevice.list(AltosLib.product_altusmetrum); - if (devices.size() != 0) - break; - } + public void do_failure() { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_failure(); } catch (Exception ex) { } + } + }); + } + + public void do_cancel() { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_cancel(); } catch (Exception ex) { } + } + }); + } + + public void run () { + try { + AltosLink link = null; + + for (;;) { + System.out.printf("Attempting to open %s\n", device.toShortString()); + + link = new AltosSerial(device); + + if (link == null) + throw new IOException(String.format("%s: open failed", + device.toShortString())); - if (devices.size() == 1) - device = devices.get(0); - else { - device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum); - if (device == null) - return false; + /* See if the link is usable already */ + if (is_pair_programmed() || link.is_loader()) { + System.out.printf("Device ready for use\n"); + do_success(link); + return; + } + + java.util.List prev_devices = + AltosUSBDevice.list(AltosLib.product_altusmetrum); + + /* Nope, switch to loader and + * wait for it to re-appear + */ + + System.out.printf("Switch to loader\n"); + + link.to_loader(); + + /* This is a bit fragile, but + * I'm not sure what else to + * do other than ask the user. + * + * Search for a device which + * wasn't there before we + * asked the target to switch + * to loader mode + */ + + device = null; + for (;;) { + Thread.sleep(100); + java.util.List devices = + AltosUSBDevice.list(AltosLib.product_altusmetrum); + + for (AltosDevice d : devices) { + boolean matched = false; + System.out.printf("\tfound device %s\n", d.toShortString()); + for (AltosDevice p : prev_devices) + if (d.equals(p)) { + matched = true; + break; + } + if (!matched) { + System.out.printf("Identified new device %s\n", d.toShortString()); + device = d; + break; + } + } + if (device != null) + break; + } } - link = new AltosSerial(device); + } catch (AltosSerialInUseException ee) { + do_exception(ee); + } catch (FileNotFoundException fe) { + do_exception(fe); + } catch (IOException ie) { + do_exception (ie); + } catch (InterruptedException ie) { } - return true; - } catch (AltosSerialInUseException ee) { - exception(ee); - } catch (FileNotFoundException fe) { - exception(fe); - } catch (IOException ie) { - exception (ie); } - return false; + + public void cancel() { + t.interrupt(); + } + + public open_task(AltosDevice device, open_dialog dialog) { + this.device = device; + this.dialog = dialog; + t = new Thread(this); + t.start(); + } + } + + class open_dialog + extends AltosUIDialog + implements ActionListener + { + AltosUIFrame owner; + + private JLabel opening_label; + private JButton cancel_button; + + boolean done = false; + + AltosLink link = null; + + open_task open = null; + + public void open_exception(Exception e) { + System.out.printf("open_exception\n"); + setVisible(false); + exception(e); + done = true; + } + + public void open_success(AltosLink link) { + System.out.printf("open_success\n"); + setVisible(false); + this.link = link; + done = true; + } + + public void open_failure() { + System.out.printf("open_failure\n"); + setVisible(false); + done = true; + } + + public void open_cancel() { + System.out.printf("open_cancel\n"); + setVisible(false); + done = true; + } + + public AltosLink do_open(open_task open) throws InterruptedException { + this.open = open; + setVisible(true); + return link; + } + + public void actionPerformed(ActionEvent e) { + String cmd = e.getActionCommand(); + + if (cmd.equals("cancel")) + if (open != null) + open.cancel(); + done = true; + setVisible(false); + } + + public open_dialog(AltosUIFrame in_owner) { + super(in_owner, "Open Flash Target Device", true); + owner = in_owner; + + Container pane = getContentPane(); + GridBagConstraints c = new GridBagConstraints(); + Insets i = new Insets(4,4,4,4); + + + pane.setLayout(new GridBagLayout()); + + opening_label = new JLabel("Opening Device"); + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.LINE_START; + c.insets = i; + c.weightx = 0; + c.weighty = 0; + + c.gridx = 0; + c.gridy = 0; + + pane.add(opening_label, c); + + cancel_button = new JButton("Cancel"); + cancel_button.addActionListener(this); + cancel_button.setActionCommand("cancel"); + + c.gridy = 1; + pane.add(cancel_button, c); + pack(); + setLocationRelativeTo(owner); + } + } + + private boolean open_device() throws InterruptedException { + + open_dialog dialog = new open_dialog(frame); + + open_task open = new open_task(device, dialog); + + link = dialog.do_open(open); + + return link != null; } /*