From 6f5bb6d3f9682989d47508a95512205f9d295ac1 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 15 Jun 2017 14:09:35 +0200 Subject: [PATCH] Code polish/cleanup. Added isWindows8_1_plus() cache various variables now (which are expensive to compute). --- src/dorkbox/util/OSUtil.java | 228 ++++++++++++++++++++++++++++++----- 1 file changed, 197 insertions(+), 31 deletions(-) diff --git a/src/dorkbox/util/OSUtil.java b/src/dorkbox/util/OSUtil.java index 7d6c479..80806d0 100644 --- a/src/dorkbox/util/OSUtil.java +++ b/src/dorkbox/util/OSUtil.java @@ -22,7 +22,6 @@ import java.io.FileReader; import java.io.PrintStream; import java.util.LinkedList; import java.util.List; -import java.util.Scanner; import dorkbox.util.process.ShellProcessBuilder; @@ -30,6 +29,7 @@ import dorkbox.util.process.ShellProcessBuilder; * Container for all OS specific tests and methods. These do not exist in OS.java, because of dependency issues (OS.java should not * depend on any native libraries) */ +@SuppressWarnings("unused") public class OSUtil { public static @@ -147,6 +147,23 @@ class OSUtil { return version[0] == 6 && version[1] == 3; } + /** + * @return is greater than or equal to windows 8.1 or equivalent + */ + public static + boolean isWindows8_1_plus() { + int[] version = getVersion(); + if (version[0] == 6 && version[1] >= 3) { + return true; + } + else if (version[0] > 6) { + return true; + } + + + return false; + } + /** * @return is windows 10 or equivalent */ @@ -182,6 +199,7 @@ class OSUtil { } } + @SuppressWarnings("WeakerAccess") public static class Linux { public static @@ -212,26 +230,33 @@ class OSUtil { if (totalLength > 0) { StringBuilder fileContents = new StringBuilder(totalLength); + BufferedReader reader = null; + for (File releaseFile : releaseFiles) { - Scanner scanner = new Scanner(releaseFile); + try { + reader = new BufferedReader(new FileReader(releaseFile)); - BufferedReader reader = new BufferedReader(new FileReader(releaseFile)); - String currentLine; + String currentLine; - // NAME="Arch Linux" - // PRETTY_NAME="Arch Linux" - // ID=arch - // ID_LIKE=archlinux - // ANSI_COLOR="0;36" - // HOME_URL="https://www.archlinux.org/" - // SUPPORT_URL="https://bbs.archlinux.org/" - // BUG_REPORT_URL="https://bugs.archlinux.org/" + // NAME="Arch Linux" + // PRETTY_NAME="Arch Linux" + // ID=arch + // ID_LIKE=archlinux + // ANSI_COLOR="0;36" + // HOME_URL="https://www.archlinux.org/" + // SUPPORT_URL="https://bbs.archlinux.org/" + // BUG_REPORT_URL="https://bugs.archlinux.org/" - // similar on other distro's. ID is always the "key" to the distro + // similar on other distro's. ID is always the "key" to the distro - while ((currentLine = reader.readLine()) != null) { - fileContents.append(currentLine) - .append(OS.LINE_SEPARATOR_UNIX); + while ((currentLine = reader.readLine()) != null) { + fileContents.append(currentLine) + .append(OS.LINE_SEPARATOR_UNIX); + } + } finally { + if (reader != null) { + reader.close(); + } } } @@ -261,6 +286,11 @@ class OSUtil { return 0; } + /** + * @param id the info ID to check, ie: ubuntu, arch, debian, etc... This is what the OS vendor uses to ID their OS. + * + * @return true if this OS is identified as the specified ID. + */ public static boolean getInfo(String id) { String output = getInfo(); @@ -268,55 +298,167 @@ class OSUtil { return output.contains("ID=" + id +"\n"); } + private static volatile Boolean isArch = null; public static boolean isArch() { - return getInfo("arch"); + if (isArch == null) { + isArch = getInfo("arch"); + } + return isArch; } + private static volatile Boolean isDebian = null; public static boolean isDebian() { - return getInfo("debian"); + if (isDebian == null) { + isDebian = getInfo("debian"); + } + return isDebian; } + private static volatile Boolean isElementaryOS = null; public static boolean isElementaryOS() { - try { - String output = getInfo(); - // ID="elementary" (notice the extra quotes) - return output.contains("ID=\"elementary\"\n") || output.contains("ID=elementary\n") || + if (isElementaryOS == null) { + try { + String output = getInfo(); + // ID="elementary" (notice the extra quotes) + isElementaryOS = output.contains("ID=\"elementary\"\n") || output.contains("ID=elementary\n") || - // this is specific to eOS < 0.3.2 - output.contains("ID=\"elementary OS\"\n"); - } catch (Throwable ignored) { + // this is specific to eOS < 0.3.2 + output.contains("ID=\"elementary OS\"\n"); + } catch (Throwable ignored) { + isElementaryOS = false; + } } - - return false; + return isElementaryOS; } + private static volatile Boolean isFedora = null; public static boolean isFedora() { - return getInfo("fedora"); + if (isFedora == null) { + isFedora = getInfo("fedora"); + } + return isFedora; } + private static volatile Boolean isLinuxMint = null; public static boolean isLinuxMint() { - return getInfo("linuxmint"); + if (isLinuxMint == null) { + isLinuxMint = getInfo("linuxmint"); + } + return isLinuxMint; + } + + private static volatile Boolean isUbuntu = null; + public static + boolean isUbuntu() { + if (isUbuntu == null) { + isUbuntu = getInfo("ubuntu"); + } + return isUbuntu; } public static - boolean isUbuntu() { - return getInfo("ubuntu"); + boolean isRoot() { + // this means we are running as sudo + boolean isSudoOrRoot = System.getenv("SUDO_USER") != null; + + if (!isSudoOrRoot) { + // running as root (also can be "sudo" user). A lot slower that checking a sys env, but this is guaranteed to work + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8196); + PrintStream outputStream = new PrintStream(byteArrayOutputStream); + + // id -u + final ShellProcessBuilder shell = new ShellProcessBuilder(outputStream); + shell.setExecutable("id"); + shell.addArgument("-u"); + shell.start(); + + String output = ShellProcessBuilder.getOutput(byteArrayOutputStream); + isSudoOrRoot = "0".equals(output); + } catch (Throwable ignored) { + } + } + + return isSudoOrRoot; } } public static class DesktopEnv { + public enum Env { + Gnome, + KDE, + Unity, + XFCE, + LXDE, + Pantheon, + Unknown, + } + + public static + Env get() { + // if we are running as ROOT, we *** WILL NOT *** have access to 'XDG_CURRENT_DESKTOP' + // *unless env's are preserved, but they are not guaranteed to be + // see: http://askubuntu.com/questions/72549/how-to-determine-which-window-manager-is-running + String XDG = System.getenv("XDG_CURRENT_DESKTOP"); + if (XDG == null) { + // maybe we are running as root??? + XDG = "unknown"; // try to autodetect if we should use app indicator or gtkstatusicon + } + + + // BLEH. if gnome-shell is running, IT'S REALLY GNOME! + // we must ALWAYS do this check!! + if (OSUtil.DesktopEnv.isGnome()) { + XDG = "gnome"; + } + else if (OSUtil.DesktopEnv.isKDE()) { + // same thing with plasmashell! + XDG = "kde"; + } + + // Ubuntu Unity is a weird combination. It's "Gnome", but it's not "Gnome Shell". + if ("unity".equalsIgnoreCase(XDG)) { + return Env.Unity; + } + else if ("xfce".equalsIgnoreCase(XDG)) { + return Env.XFCE; + } + else if ("lxde".equalsIgnoreCase(XDG)) { + return Env.LXDE; + } + else if ("kde".equalsIgnoreCase(XDG)) { + return Env.KDE; + } + else if ("pantheon".equalsIgnoreCase(XDG)) { + return Env.Pantheon; + } + else if ("gnome".equalsIgnoreCase(XDG)) { + return Env.Gnome; + } + + return Env.Unknown; + } + + + private static volatile Boolean isGnome = null; + private static volatile Boolean isKDE = null; + public static boolean isGnome() { if (!OS.isLinux() && !OS.isUnix()) { return false; } + if (isGnome != null) { + return isGnome; + } + try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8196); PrintStream outputStream = new PrintStream(byteArrayOutputStream); @@ -346,10 +488,12 @@ class OSUtil { contains = output.contains("gnome-shell"); } + isGnome = contains; return contains; } catch (Throwable ignored) { } + isGnome = false; return false; } @@ -385,6 +529,28 @@ class OSUtil { return null; } + public static + boolean isKDE() { + if (isKDE != null) { + return isKDE; + } + + String XDG = System.getenv("XDG_CURRENT_DESKTOP"); + if (XDG == null) { + // Check if plasmashell is running, if it is -- then we are most likely KDE + double plasmaVersion = OSUtil.DesktopEnv.getPlasmaVersion(); + + isKDE = plasmaVersion > 0; + return isKDE; + } else if ("kde".equalsIgnoreCase(XDG)) { + isKDE = true; + return false; + } + + isKDE = false; + return false; + } + // cannot represent '5.6.5' as a number, so we return just the first two decimal places instead public static double getPlasmaVersion() {