Example usage for java.util Collection notifyAll

List of usage examples for java.util Collection notifyAll

Introduction

In this page you can find the example usage for java.util Collection notifyAll.

Prototype

@HotSpotIntrinsicCandidate
public final native void notifyAll();

Source Link

Document

Wakes up all threads that are waiting on this object's monitor.

Usage

From source file:com.lfv.lanzius.application.Controller.java

public synchronized void stop(boolean leaveChannels, boolean waitChannelsLeft) {
    try {/*from  w w  w. j  a v  a2 s  . c o  m*/
        long t = System.currentTimeMillis();
        while (!semStartFinished && (System.currentTimeMillis() < (t + TIMEOUT_STARTSTOP)))
            wait(100);
    } catch (InterruptedException ex) {
    }

    if (autoTesterEnabled && autoTester != null) {
        autoTester.stopTester();
    }

    semChannelsLeft = true;
    if (state == CLIENT_STATE_STARTED) {

        log.info("Stopping session");

        state = CLIENT_STATE_CONNECTED;

        // Stop all sounds
        playSound(SOUND_NONE);

        if (footSwitch != null)
            footSwitch.stop();

        if (peripheralLink != null)
            peripheralLink.PostRadioSendStop();

        if (view != null) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    view.setVisible(false);
                    view.dispose();
                }
            });
        }

        if (leaveChannels && bundle != null && !Config.CLIENT_SERVERLESS) {
            // Leave all channels
            Collection<Integer> c = new LinkedList<Integer>();
            Iterator<ClientChannel> iterc = bundle.getChannelCollection().iterator();
            while (iterc.hasNext()) {
                ClientChannel channel = iterc.next();
                c.add(new Integer(channel.getId()));
            }

            semChannelsLeft = c.isEmpty();
            if (!semChannelsLeft)
                networkManager.sessionDisconnect();
        }

        // Stop decoder and close channels
        Iterator<ItemDispatcher> iterd = packetReceiver.getDataPacketDispatcherCollection().iterator();
        while (iterd.hasNext()) {
            AudioDecoder decoder = (AudioDecoder) iterd.next();
            int channelId = decoder.getDecoderId();
            packetReceiver.closeChannel(channelId);
            if (audioRecorder != null) {
                audioRecorder.stopRecording(channelId);
            }
            decoder.stopModule();
        }

        // Stop encoders
        if (encoder != null) {
            encoder.stopModule();
        }
        if (monitorEncoder != null) {
            monitorEncoder.stopModule();
        }

        packetReceiver.removeDataPacketDispatchers();
        volumeRadioList.clear();
        decoderPhone = null;
        decoderForward = null;
        encoder = null;
        monitorEncoder = null;

        model = null;

        sleep(25);

        if (distributor != null) {
            distributor.removeAll();
            distributor = null;
        }
        if (monitorDistributor != null) {
            monitorDistributor.removeAll();
            monitorDistributor = null;
        }

        log.debug("Session stopped, Waiting for start session packet from server");

        // The system is not allowed to be started immediately after stop
        if (timer != null) {
            semStopFinished = false;
            timer.schedule(new TimerTask() {
                public void run() {
                    Controller c = Controller.getInstance();
                    synchronized (c) {
                        semStopFinished = true;
                        c.notifyAll();
                    }
                }
            }, DELAY_STARTSTOP);
        }

        if (leaveChannels && waitChannelsLeft && !semChannelsLeft && !Config.CLIENT_SERVERLESS) {
            try {

                long t = System.currentTimeMillis();
                while (!semChannelsLeft && (System.currentTimeMillis() < (t + TIMEOUT_LEAVE)))
                    wait(100);

                if (!semChannelsLeft)
                    log.warn("Wait for channels left timed out!");

            } catch (InterruptedException ex) {
                log.warn("Wait for channels left interrupted!");
            }
        }
    }
}

From source file:com.lfv.lanzius.application.Controller.java

public synchronized void start() {
    try {/*  www. ja  v a  2  s .  com*/
        long t = System.currentTimeMillis();
        while (!semStopFinished && (System.currentTimeMillis() < (t + TIMEOUT_STARTSTOP)))
            wait(100);
    } catch (InterruptedException ex) {
    }

    if (state == CLIENT_STATE_CONNECTED) {

        view = null;
        audioRecorder = null;

        log.info("Starting session");

        radioState = RADIO_STATE_IDLE;
        phoneState = PHONE_STATE_IDLE;
        phoneActive = false;
        radioEncoding = false;
        radioDecoding = false;
        radioDecodingList.clear();

        log.debug("Downloading data model for terminal " + properties.getTerminalId() + " from http://"
                + properties.getServerAddress() + ":" + properties.getServerHttpPort());
        // Get configuration document from server
        String url = "http://" + properties.getServerAddress() + ":" + properties.getServerHttpPort()
                + "/xml/info?terminal=" + properties.getTerminalId();
        try {
            SAXBuilder builder = new SAXBuilder();
            if (Config.CLIENT_SERVERLESS)
                model = builder.build(new java.io.File("data/development/client_inforequest.xml"));
            else
                model = builder.build(new URL(url));
        } catch (Exception ex) {
            log.error("Failed to get or parse the configuration document from " + url.toString(), ex);
            log.debug("Waiting for start session packet from server");
            ex.printStackTrace();
            return;
        }

        if (!validateModel()) {
            log.error("Invalid data model, validation failed!");
            log.debug("Waiting for start session packet from server");
            return;
        }

        // Document is valid
        state = CLIENT_STATE_STARTED;
        log.debug("Data model passed validation test");

        // Add extra nodes
        model.getRootElement().addContent(new Element("TalkButton"));
        model.getRootElement().addContent(new Element("HookButton"));
        Element e1 = new Element("Settings");
        Element e2 = new Element("Name");
        e2.setText("SETTINGS");
        e1.addContent(e2);
        e1.setAttribute("hfac", "0.4");
        model.getRootElement().addContent(e1);

        // Inactivate all phone peers initially
        Iterator iter1 = model.getRootElement().getChild("RoleSetup").getChildren().iterator();
        while (iter1.hasNext()) {
            Element er = (Element) iter1.next();
            Iterator iter2 = er.getChild("PhonePeers").getChildren().iterator();
            while (iter2.hasNext()) {
                Element err = (Element) iter2.next();
                err.setAttribute("active", "false");
            }
        }

        // Clear
        encoder = null;
        distributor = null;
        decoderPhone = null;
        decoderForward = null;
        monitorEncoder = null;
        monitorDistributor = null;

        // Get codec type
        String codec = DomTools.getChildText(model.getRootElement(), "Codec", "null", true);

        // Encoder
        if (codec.startsWith("jspeex")) {
            // Parse out the quality from the string "jspeex:<quality 1-10>"
            int quality = 6;
            int idx = codec.indexOf(':');
            if (idx > 0) {
                try {
                    quality = Integer.parseInt(codec.substring(idx + 1));
                } catch (Exception ex) {
                    log.warn("Parse error in string " + codec
                            + ", should be \"jspeex:<quality 1-10>\", defaulting to 6!");
                }
                if (quality < 1 || quality > 10) {
                    log.warn("Out of range error in string " + codec
                            + ", should be \"jspeex:<quality 1-10>\", defaulting to 6!");
                    quality = 6;
                }
            }
            encoder = new JSpeexEncoder(inputMixer, quality);
            monitorEncoder = new JSpeexEncoder(inputMixer, quality);
        } else {
            encoder = new NullEncoder(inputMixer);
            monitorEncoder = new NullEncoder(inputMixer);
        }

        // Main distributor
        distributor = new Distributor(properties.getTerminalId(), bundle, networkManager.getSender());
        encoder.setPacketDistributor(distributor);

        // Monitor distributor
        monitorDistributor = new Distributor(properties.getTerminalId(), bundle, networkManager.getSender());
        monitorEncoder.setPacketDistributor(monitorDistributor);

        // Start encoders
        AudioFormat audioFormats[] = encoder.getSupportedAudioFormats();
        int usedAudioFormat = -1;

        // Find which audio format to use
        for (int i = 0; i < audioFormats.length; i++) {
            try {
                encoder.startModule(i);
                log.debug("Using input audio format " + audioFormats[i]);
                usedAudioFormat = i;
                break;
            } catch (Exception ex) {
                log.warn("Could not open the input device for format " + audioFormats[i] + "!");
            }
        }

        if (usedAudioFormat < 0) {
            log.error("Unable to start, the input sound device is unavailable!");
            stop(false, false);
            return;
        }

        MixingDataLine monitorDataLine = null;
        if (usedAudioFormat > 0) {
            log.warn("Unable to open the monitor data line, supports mono only!");
            monitorEncoder = null;
            monitorDistributor = null;
        } else {

            // Create a mixing data line for the monitor
            monitorDataLine = new MixingDataLine();

            try {
                // Start monitor encoder with the same format as the main encoder
                monitorEncoder.startModule(monitorDataLine, 0);

            } catch (Exception ex) {
                log.warn("Unable to open the monitor data line, monitoring has been disabled!", ex);
                monitorDataLine = null;
                monitorEncoder = null;
                monitorDistributor = null;
            }
        }

        // Pass a monitor channel to the encoder
        if (monitorDataLine != null) {
            encoder.setMonitorChannel(monitorDataLine.getMixerChannel());
        }

        // Create decoders and packet dispatchers
        if (codec.startsWith("jspeex")) {
            decoderPhone = new JSpeexDecoder(outputMixer, CHANNEL_PHONE);
            decoderForward = new JSpeexDecoder(outputMixer, CHANNEL_FORWARD);
        } else {
            decoderPhone = new NullDecoder(outputMixer, CHANNEL_PHONE);
            decoderForward = new NullDecoder(outputMixer, CHANNEL_FORWARD);
        }

        // Add decoders as packet receiver handlers
        packetReceiver.addDataPacketDispatcher(CHANNEL_PHONE, decoderPhone);
        packetReceiver.addDataPacketDispatcher(CHANNEL_FORWARD, decoderForward);

        // Pass monitor channel to decoders
        if (monitorDataLine != null) {
            decoderPhone.setMonitorChannel(monitorDataLine.getMixerChannel());
            decoderForward.setMonitorChannel(monitorDataLine.getMixerChannel());
        }

        Iterator iter = model.getRootElement().getChild("ChannelSetup").getChildren().iterator();
        while (iter.hasNext()) {
            Element ec = (Element) iter.next();
            int channelId = DomTools.getAttributeInt(ec, "id", 0, true);
            if (channelId > 0) {
                AudioDecoder decoder;
                if (codec.startsWith("jspeex")) {
                    decoder = new JSpeexDecoder(outputMixer, channelId);
                } else {
                    decoder = new NullDecoder(outputMixer, channelId);
                }

                // Add decoder as packet receiver handler
                packetReceiver.addDataPacketDispatcher(channelId, decoder);

                // Pass monitor channel to decoder
                if (monitorDataLine != null) {
                    decoder.setMonitorChannel(monitorDataLine.getMixerChannel());
                }
            }
        }

        // Go through the decoders and create output lines for them
        audioFormats = null;
        usedAudioFormat = -1;
        iter = packetReceiver.getDataPacketDispatcherCollection().iterator();
        while (iter.hasNext()) {
            AudioDecoder decoder = (AudioDecoder) iter.next();

            // First iteration, find which audio format to use
            if (usedAudioFormat < 0) {
                audioFormats = decoder.getSupportedAudioFormats();
                for (int i = 0; i < audioFormats.length; i++) {
                    try {
                        decoder.startModule(i);
                        log.debug("Using output audio format " + audioFormats[i]);
                        usedAudioFormat = i;
                        break;
                    } catch (Exception ex) {
                        log.warn("Could not open the output device for format " + audioFormats[i] + "!");
                    }
                }

                if (usedAudioFormat < 0) {
                    log.error("Unable to start, the output sound device is unavailable!");
                    stop(false, false);
                    return;
                }
            }

            // The format to use is known, just start the module
            else {
                try {
                    decoder.startModule(usedAudioFormat);
                } catch (LineUnavailableException ex) {
                    log.error("Could not open the output device for format " + audioFormats[usedAudioFormat]
                            + "!");
                    stop(false, false);
                    return;
                }
            }

            // Add listeners for all radio
            // Also add to volume list
            if (decoder.getDecoderId() > CHANNEL_RADIO_START) {
                decoder.addListener(this);
                volumeRadioList.add(decoder);
            }
        }

        // Create a recorder
        audioRecorder = new AudioRecorder(audioFormats[usedAudioFormat], true);

        // Join channels
        Collection<Integer> c = new LinkedList<Integer>();
        // Common
        bundle.addChannel(new ClientChannel(CHANNEL_COMMON));
        c.add(CHANNEL_COMMON);
        iter = model.getRootElement().getChild("ChannelSetup").getChildren().iterator();
        while (iter.hasNext()) {
            Element ec = (Element) iter.next();
            int channelId = DomTools.getAttributeInt(ec, "id", 0, true);
            if (channelId > 0) {
                ClientChannel channel = new ClientChannel(channelId);
                bundle.addChannel(channel);
                c.add(channelId);
                // Also store the channel element..
                channel.setElement(ec);
                // ..and the decoder for fast access
                AudioDecoder decoder = (AudioDecoder) packetReceiver.getDataPacketDispatcher(channelId);
                channel.setDecoder(decoder);
                // finally, add the recorder if the channel has recordable="true"
                if (DomTools.getAttributeBoolean(ec, "recordable", false, false)) {
                    decoder.setAudioRecorder(audioRecorder);
                    decoder.addListener(audioRecorder); // to get stop events for injecting silence
                }
            }
        }

        networkManager.sessionConnect(c);

        // Immediately open all channels with state rxtx or rx
        iter = bundle.getChannelCollection().iterator();
        while (iter.hasNext()) {
            ClientChannel channel = (ClientChannel) iter.next();
            if (!DomTools.getAttributeString(channel.getElement(), "state", "off", false).equals("off")) {
                packetReceiver.openChannel(channel.getId());
            }
        }

        // Force all settings
        Settings settings = Settings.getInstance();
        settingsValueChanged(Settings.ID_MASTER_VOLUME, settings.getMasterVolume());
        settingsValueChanged(Settings.ID_SIGNAL_VOLUME, settings.getSignalVolume());
        settingsValueChanged(Settings.ID_CHPRIO_VOLUME, settings.getChprioVolume());
        settingsValueChanged(Settings.ID_RAPASS_VOLUME, settings.getRapassVolume());
        settingsValueChanged(Settings.ID_CHPRIO_CHOICE, settings.getChprioChoice());
        settingsValueChanged(Settings.ID_WATONE_CHOICE, settings.getWatoneChoice());

        // Create view
        String style = properties.getUserInterfaceStyle().toLowerCase();
        if (!(style.equals("full") || style.equals("slim-phone") || style.equals("slim-horiz")
                || style.equals("slim-vert") || style.equals("none"))) {
            log.warn("Invalid user interface style (" + style + ") defaulting to full!");
            style = "full";
            properties.setUserInterfaceStyle(style);
        }

        if (!Config.CLIENT_SIZE_FULLSCREEN || !style.equals("full"))
            JFrame.setDefaultLookAndFeelDecorated(true);

        log.debug("Creating view with style: " + style);

        if (properties.getUserInterfaceStyle().equalsIgnoreCase("full")) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    view = new FullView(Controller.getInstance(), properties);
                    view.setModel(model);
                    view.setVisible(true);
                    view.toFront();
                    if (peripheralLink != null)
                        peripheralLink.setView(view);
                }
            });
        } else if (properties.getUserInterfaceStyle().equalsIgnoreCase("none")) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    view = new FullView(Controller.getInstance(), properties);
                    view.setModel(model);
                    view.setVisible(false);
                    view.toFront();
                    if (peripheralLink != null)
                        peripheralLink.setView(view);
                }
            });
        } else if (properties.getUserInterfaceStyle().equalsIgnoreCase("slim-phone")) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    view = new PhoneOnlyView(Controller.getInstance(), properties);
                    view.setModel(model);
                    view.setVisible(true);
                    view.toFront();
                    if (peripheralLink != null)
                        peripheralLink.setView(view);
                }
            });
        } else {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    view = new SlimView(Controller.getInstance(), properties);
                    view.setModel(model);
                    view.setVisible(true);
                    view.toFront();
                    if (peripheralLink != null)
                        peripheralLink.setView(view);
                }
            });
        }

        // Start the push to talk interfaces
        if (properties.getEventDeviceName().length() > 0) {
            eventSwitch.start();
        }
        if (properties.getFootSwitchInterface().length() > 0) {
            if (footSwitch != null) {
                try {
                    footSwitch.start();
                } catch (UnsatisfiedLinkError err) {
                    log.error("UnsatisfiedLinkError: " + err.getMessage());
                    log.warn("Missing ftsw library (ftsw.dll or libftsw.so)");
                    if (!properties.getFootSwitchInterface().equalsIgnoreCase("ftdi"))
                        log.warn("Missing rxtxSerial library (rxtxSerial.dll or librxtxSerial.so)");
                    log.warn("The footswitch has been disabled!");
                    footSwitch = null;
                } catch (NoClassDefFoundError err) {
                    log.warn("Missing ftsw library (ftsw.dll or libftsw.so)");
                    if (!properties.getFootSwitchInterface().equalsIgnoreCase("ftdi"))
                        log.warn("Missing rxtxSerial library (rxtxSerial.dll or librxtxSerial.so)");
                    log.warn("The footswitch has been disabled!");
                    footSwitch = null;
                } catch (NoSuchPortException ex) {
                    log.warn("The serial port " + properties.getFootSwitchInterface()
                            + " does not exist, the footswitch has been disabled!");
                    footSwitch = null;
                } catch (PortInUseException ex) {
                    log.warn("The serial port " + properties.getFootSwitchInterface()
                            + " is already in use, the footswitch has been disabled!");
                    footSwitch = null;
                }
            }
        }

        sleep(25);

        dbgListThreads();

        // The system is not allowed to be stopped immediately after start
        if (timer != null) {
            semStartFinished = false;
            timer.schedule(new TimerTask() {
                public void run() {
                    Controller c = Controller.getInstance();
                    synchronized (c) {
                        semStartFinished = true;
                        c.notifyAll();
                    }
                }
            }, DELAY_STARTSTOP);
        }

        if (autoTesterEnabled && autoTester != null) {
            autoTester.startTester(model);
        }
    }
}