com.github.mike10004.xvfbmanager.DefaultDisplayReadinessChecker Maven / Gradle / Ivy
The newest version!
package com.github.mike10004.xvfbmanager;
import com.google.common.collect.ImmutableSet;
import io.github.mike10004.subprocess.ProcessMonitor;
import io.github.mike10004.subprocess.ProcessResult;
import io.github.mike10004.subprocess.ProcessTracker;
import io.github.mike10004.subprocess.Subprocess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import static java.util.Objects.requireNonNull;
/**
* Class that calls an X program to gather information about a display in order
* to determine whether the display is ready. Executes {@code xdpyinfo}, specifying
* the {@code -display} argument, and interprets a clean exit to indicate that
* the display is ready.
*/
public class DefaultDisplayReadinessChecker implements XvfbManager.DisplayReadinessChecker {
private static final Logger log = LoggerFactory.getLogger(DefaultDisplayReadinessChecker.class);
private static final String PROG_XDPYINFO = "xdpyinfo";
private static final ImmutableSet requiredPrograms = ImmutableSet.of(PROG_XDPYINFO);
private final ProcessTracker processTracker;
public DefaultDisplayReadinessChecker(ProcessTracker processTracker) {
this.processTracker = requireNonNull(processTracker);
}
public static Iterable getRequiredPrograms() {
return requiredPrograms;
}
private static final int XDPYINFO_SIGTERM_TIMEOUT_MILLIS = 1000;
/**
* Checks display readiness. Executes {@code xdpyinfo} and returns true on
* a clean exit code.
* @param display the display to check, e.g. ":123"
* @return true iff {@code xdpyinfo} exits clean
*/
@Override
public boolean checkReadiness(String display) {
ProcessMonitor monitor = Subprocess.running("xdpyinfo")
.args("-display", display)
.build()
.launcher(processTracker)
.outputStrings(Charset.defaultCharset()) // xdpyinfo uses platform charset, presumably
.launch();
ProcessResult result;
try {
result = monitor.await();
} catch (InterruptedException e) {
log.error("interrupted while waiting for check readiness", e);
ProcessKilling.termOrKill(monitor.destructor(), XDPYINFO_SIGTERM_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
return false;
}
executedCheckProgram(result);
return representsReady(result, display);
}
protected boolean representsReady(ProcessResult result, String requiredDisplay) {
if (result.exitCode() != 0) {
return false;
}
return isCorrectOutputForDisplay(result.content().stdout(), requiredDisplay);
}
protected static boolean isCorrectOutputForDisplay(String stdout, String requiredDisplay) {
Pattern pattern = Pattern.compile("^name of display:\\s+" + Pattern.quote(requiredDisplay) + "$", Pattern.MULTILINE);
return pattern.matcher(stdout).find();
}
protected void executedCheckProgram(ProcessResult result) {
LoggerFactory.getLogger(DefaultDisplayReadinessChecker.class).debug("xdpyinfo: {}", result);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy