All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robovm.compiler.target.ios.AppLauncherProcess Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2013 RoboVM AB
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.robovm.compiler.target.ios;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.robovm.compiler.log.ErrorOutputStream;
import org.robovm.compiler.log.Logger;
import org.robovm.compiler.target.LaunchParameters;
import org.robovm.compiler.target.Launcher;
import org.robovm.compiler.util.io.OpenOnWriteFileOutputStream;
import org.robovm.libimobiledevice.util.AppLauncher;

/**
 * {@link Process} implementation which runs an app on a device using an
 * {@link AppLauncher}.
 */
public class AppLauncherProcess extends Process implements Launcher {
    private final AtomicInteger threadCounter = new AtomicInteger();
    private final Logger log;
    private final AppLauncher launcher;
    private final WaitInputStream in = new WaitInputStream();
    private final WaitInputStream err = new WaitInputStream();
    private final CountDownLatch countDownLatch = new CountDownLatch(1);
    private Thread launcherThread;
    private volatile boolean finished = false;
    private volatile int exitCode = -1;
    private OutputStream errStream;

    public AppLauncherProcess(Logger log, AppLauncher launcher, LaunchParameters launchParameters) {
        this.log = log;
        this.launcher = launcher;
        if (launchParameters.getStderrFifo() != null) {
            this.errStream = new OpenOnWriteFileOutputStream(launchParameters.getStderrFifo());
        }
    }

    @Override
    public Process execAsync() throws IOException {
        this.launcherThread = new Thread("AppLauncherThread-" + threadCounter.getAndIncrement()) {
            @Override
            public void run() {
                try {
                    // install and launch
                    exitCode = launcher.launch();
                } catch (Throwable t) {
                    log.error("AppLauncher failed with an exception:", t.getMessage());
                    t.printStackTrace(new PrintStream(new ErrorOutputStream(log), true));
                } finally {
                    IOUtils.closeQuietly(errStream);
                    finished = true;
                    countDownLatch.countDown();
                }
            }
        };
        this.launcherThread.start();
        return this;
    }
    
    @Override
    public OutputStream getOutputStream() {
        return new NullOutputStream();
    }

    @Override
    public InputStream getInputStream() {
        return in;
    }

    @Override
    public InputStream getErrorStream() {
        return err;
    }

    @Override
    public int waitFor() throws InterruptedException {
        countDownLatch.await();
        return exitCode;
    }

    @Override
    public int exitValue() {
        if (!finished) {
            throw new IllegalThreadStateException("Not terminated");
        }
        return exitCode;
    }

    @Override
    public void destroy() {
        launcher.kill();
    }

    private class WaitInputStream extends InputStream {

        @Override
        public int read() throws IOException {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                throw new InterruptedIOException();
            }
            return -1;
        }
        
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy