diff --git a/api/src/main/java/io/xpipe/api/connector/XPipeApiConnection.java b/api/src/main/java/io/xpipe/api/connector/XPipeApiConnection.java index de6d332d..1e07a5e7 100644 --- a/api/src/main/java/io/xpipe/api/connector/XPipeApiConnection.java +++ b/api/src/main/java/io/xpipe/api/connector/XPipeApiConnection.java @@ -6,6 +6,7 @@ import io.xpipe.beacon.BeaconException; import io.xpipe.beacon.BeaconServer; import io.xpipe.beacon.exchange.cli.DialogExchange; import io.xpipe.core.dialog.DialogReference; +import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeInstallation; import java.util.Optional; @@ -133,7 +134,7 @@ public final class XPipeApiConnection extends BeaconConnection { private void start() throws Exception { var installation = XPipeInstallation.getLocalDefaultInstallationBasePath(true); - BeaconServer.start(installation); + BeaconServer.start(installation, XPipeDaemonMode.BACKGROUND); } @FunctionalInterface diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconDaemonController.java b/beacon/src/main/java/io/xpipe/beacon/BeaconDaemonController.java index 248769ca..52b3ca5f 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconDaemonController.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconDaemonController.java @@ -1,5 +1,6 @@ package io.xpipe.beacon; +import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeInstallation; import java.io.IOException; @@ -8,7 +9,7 @@ public class BeaconDaemonController { private static boolean alreadyStarted; - public static void start() throws Exception { + public static void start(XPipeDaemonMode mode) throws Exception { if (BeaconServer.isRunning()) { alreadyStarted = true; return; @@ -20,7 +21,7 @@ public class BeaconDaemonController { custom = true; } else { var defaultBase = XPipeInstallation.getLocalDefaultInstallationBasePath(true); - process = BeaconServer.start(defaultBase); + process = BeaconServer.start(defaultBase, mode); } waitForStartup(process, custom); diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java b/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java index 502c0c29..bf9a79d0 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconServer.java @@ -4,6 +4,7 @@ import io.xpipe.beacon.exchange.StopExchange; import io.xpipe.core.impl.FileNames; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellTypes; +import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeInstallation; import java.io.BufferedReader; @@ -39,10 +40,10 @@ public class BeaconServer { return null; } - public static Process start(String installationBase) throws Exception { + public static Process start(String installationBase, XPipeDaemonMode mode) throws Exception { String command; if (!BeaconConfig.launchDaemonInDebugMode()) { - command = XPipeInstallation.createExternalAsyncLaunchCommand(installationBase, BeaconConfig.getDaemonArguments()); + command = XPipeInstallation.createExternalAsyncLaunchCommand(installationBase, mode, BeaconConfig.getDaemonArguments()); } else { command = XPipeInstallation.createExternalLaunchCommand( getDaemonDebugExecutable(installationBase), BeaconConfig.getDaemonArguments()); diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java index 40c23a7d..4f41d1e2 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/FocusExchange.java @@ -2,7 +2,9 @@ package io.xpipe.beacon.exchange; import io.xpipe.beacon.RequestMessage; import io.xpipe.beacon.ResponseMessage; +import io.xpipe.core.util.XPipeDaemonMode; import lombok.Builder; +import lombok.NonNull; import lombok.Value; import lombok.extern.jackson.Jacksonized; @@ -17,6 +19,8 @@ public class FocusExchange implements MessageExchange { @Builder @Value public static class Request implements RequestMessage { + @NonNull + XPipeDaemonMode mode; } @Jacksonized diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java index ca884278..41c530f4 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/cli/ModeExchange.java @@ -3,6 +3,7 @@ package io.xpipe.beacon.exchange.cli; import io.xpipe.beacon.RequestMessage; import io.xpipe.beacon.ResponseMessage; import io.xpipe.beacon.exchange.MessageExchange; +import io.xpipe.core.util.XPipeDaemonMode; import lombok.Builder; import lombok.NonNull; import lombok.Value; @@ -20,12 +21,14 @@ public class ModeExchange implements MessageExchange { @Value public static class Request implements RequestMessage { @NonNull - String modeId; + XPipeDaemonMode mode; } @Jacksonized @Builder @Value public static class Response implements ResponseMessage { + @NonNull + XPipeDaemonMode usedMode; } } diff --git a/core/src/main/java/io/xpipe/core/util/SecretProvider.java b/core/src/main/java/io/xpipe/core/util/SecretProvider.java index 3c62fcaa..ac7082ca 100644 --- a/core/src/main/java/io/xpipe/core/util/SecretProvider.java +++ b/core/src/main/java/io/xpipe/core/util/SecretProvider.java @@ -4,13 +4,17 @@ import java.util.ServiceLoader; public abstract class SecretProvider { - private static final SecretProvider INSTANCE = ServiceLoader.load(ModuleLayer.boot(), SecretProvider.class).findFirst().orElseThrow(); + private static SecretProvider INSTANCE; public abstract byte[] encrypt(byte[] c); public abstract byte[] decrypt(byte[] c); public static SecretProvider get() { + if (INSTANCE == null) { + INSTANCE = ServiceLoader.load(ModuleLayer.boot(), SecretProvider.class).findFirst().orElseThrow(); + } + return INSTANCE; } } diff --git a/core/src/main/java/io/xpipe/core/util/XPipeDaemonMode.java b/core/src/main/java/io/xpipe/core/util/XPipeDaemonMode.java new file mode 100644 index 00000000..d76d5e38 --- /dev/null +++ b/core/src/main/java/io/xpipe/core/util/XPipeDaemonMode.java @@ -0,0 +1,42 @@ +package io.xpipe.core.util; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +public enum XPipeDaemonMode { + @JsonProperty("background") + BACKGROUND("background", List.of("base", "background")), + + @JsonProperty("tray") + TRAY("tray", List.of("tray", "taskbar")), + + @JsonProperty("gui") + GUI("gui", List.of("gui", "desktop", "interface")); + + public static XPipeDaemonMode get(String name) { + return Arrays.stream(XPipeDaemonMode.values()) + .filter(xPipeDaemonMode -> + xPipeDaemonMode.getNameAlternatives().contains(name.toLowerCase(Locale.ROOT))) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("Unknown mode: " + name + ". Possible values: " + + Arrays.stream(values()) + .map(XPipeDaemonMode::getDisplayName) + .collect(Collectors.joining(", ")))); + } + + @Getter + private final String displayName; + + @Getter + private final List nameAlternatives; + + XPipeDaemonMode(String displayName, List nameAlternatives) { + this.displayName = displayName; + this.nameAlternatives = nameAlternatives; + } +} diff --git a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java index 15b38022..0a296446 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -11,15 +11,15 @@ import java.util.List; public class XPipeInstallation { - public static String createExternalAsyncLaunchCommand(String installationBase, String arguments) { + public static String createExternalAsyncLaunchCommand(String installationBase, XPipeDaemonMode mode, String arguments) { var suffix = (arguments != null ? " " + arguments : ""); if (OsType.getLocal().equals(OsType.LINUX)) { - return "nohup \"" + installationBase + "/app/bin/xpiped\" --external" + suffix + " & disown"; + return "nohup \"" + installationBase + "/app/bin/xpiped\" --mode " + mode.getDisplayName() + suffix + " & disown"; } else if (OsType.getLocal().equals(OsType.MAC)) { - return "open \"" + installationBase + "\" --args --external" + suffix; + return "open \"" + installationBase + "\" --args --mode " + mode.getDisplayName() + suffix; } - return "\"" + FileNames.join(installationBase, XPipeInstallation.getDaemonExecutablePath(OsType.getLocal())) + "\" --external" + suffix; + return "\"" + FileNames.join(installationBase, XPipeInstallation.getDaemonExecutablePath(OsType.getLocal())) + "\" --mode " + mode.getDisplayName() + suffix; } public static String createExternalLaunchCommand(String command, String arguments) { diff --git a/extension/src/main/java/io/xpipe/extension/util/DaemonExtensionTest.java b/extension/src/main/java/io/xpipe/extension/util/DaemonExtensionTest.java index 01d2b07a..43ae403e 100644 --- a/extension/src/main/java/io/xpipe/extension/util/DaemonExtensionTest.java +++ b/extension/src/main/java/io/xpipe/extension/util/DaemonExtensionTest.java @@ -4,6 +4,7 @@ import io.xpipe.api.DataSource; import io.xpipe.beacon.BeaconDaemonController; import io.xpipe.core.store.DataStore; import io.xpipe.core.util.JacksonMapper; +import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeSession; import io.xpipe.extension.XPipeServiceProviders; import org.junit.jupiter.api.AfterAll; @@ -30,7 +31,7 @@ public class DaemonExtensionTest extends ExtensionTest { JacksonMapper.initModularized(ModuleLayer.boot()); XPipeServiceProviders.load(ModuleLayer.boot()); XPipeSession.init(UUID.randomUUID()); - BeaconDaemonController.start(); + BeaconDaemonController.start(XPipeDaemonMode.TRAY); } @AfterAll