diff --git a/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java b/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java index eb7a9400f..1316c50d1 100644 --- a/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java +++ b/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java @@ -17,16 +17,17 @@ public final class LazyInitializer { * @return The initialized value */ public static T initializeLazily(AtomicReference reference, Supplier factory) { - final T existingInstance = reference.get(); - if (existingInstance != null) { - return existingInstance; + final T existing = reference.get(); + if (existing != null) { + return existing; } else { - final T newInstance = factory.get(); - if (reference.compareAndSet(null, newInstance)) { - return newInstance; - } else { - return reference.get(); - } + return reference.updateAndGet(currentValue -> { + if (currentValue == null) { + return factory.get(); + } else { + return currentValue; + } + }); } } diff --git a/main/ui/pom.xml b/main/ui/pom.xml index 2c261d3ad..6ceb70390 100644 --- a/main/ui/pom.xml +++ b/main/ui/pom.xml @@ -54,6 +54,11 @@ org.cryptomator frontend-webdav + + org.cryptomator + jni + 1.0.0-SNAPSHOT + diff --git a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorComponent.java b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorComponent.java index 7c047b213..e82e006e9 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorComponent.java +++ b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorComponent.java @@ -13,8 +13,8 @@ import java.util.concurrent.ExecutorService; import javax.inject.Singleton; +import org.cryptomator.jni.MacFunctions; import org.cryptomator.ui.controllers.MainController; -import org.cryptomator.ui.jni.MacFunctions; import org.cryptomator.ui.settings.Localization; import org.cryptomator.ui.util.AsyncTaskService; import org.cryptomator.ui.util.DeferredCloser; @@ -38,4 +38,5 @@ interface CryptomatorComponent { ExitUtil exitUtil(); Optional nativeMacFunctions(); -} \ No newline at end of file + +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java index 7d8d86d0c..f4cc072ae 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java @@ -8,6 +8,7 @@ *******************************************************************************/ package org.cryptomator.ui; +import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -19,7 +20,8 @@ import org.cryptomator.crypto.engine.impl.CryptoEngineModule; import org.cryptomator.frontend.FrontendFactory; import org.cryptomator.frontend.webdav.WebDavModule; import org.cryptomator.frontend.webdav.WebDavServer; -import org.cryptomator.ui.jni.JniModule; +import org.cryptomator.jni.JniModule; +import org.cryptomator.jni.MacFunctions; import org.cryptomator.ui.model.VaultObjectMapperProvider; import org.cryptomator.ui.settings.Settings; import org.cryptomator.ui.settings.SettingsProvider; @@ -34,7 +36,7 @@ import dagger.Provides; import javafx.application.Application; import javafx.stage.Stage; -@Module(includes = {CryptoEngineModule.class, CommonsModule.class, WebDavModule.class, JniModule.class}) +@Module(includes = {CryptoEngineModule.class, CommonsModule.class, WebDavModule.class}) class CryptomatorModule { private static final Logger LOG = LoggerFactory.getLogger(CryptomatorModule.class); @@ -100,4 +102,10 @@ class CryptomatorModule { return closer.closeLater(webDavServer, WebDavServer::stop).get().orElseThrow(IllegalStateException::new); } + @Provides + @Singleton + Optional provideMacFunctions() { + return JniModule.macFunctions(); + } + } diff --git a/main/ui/src/main/java/org/cryptomator/ui/ExitUtil.java b/main/ui/src/main/java/org/cryptomator/ui/ExitUtil.java index 8bbac3ea6..7352d149c 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/ExitUtil.java +++ b/main/ui/src/main/java/org/cryptomator/ui/ExitUtil.java @@ -33,8 +33,9 @@ import javax.script.ScriptException; import javax.swing.SwingUtilities; import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.ui.jni.JniException; -import org.cryptomator.ui.jni.MacFunctions; +import org.cryptomator.jni.JniException; +import org.cryptomator.jni.MacApplicationUiState; +import org.cryptomator.jni.MacFunctions; import org.cryptomator.ui.settings.Localization; import org.cryptomator.ui.settings.Settings; import org.slf4j.Logger; @@ -93,7 +94,7 @@ class ExitUtil { if (Platform.isImplicitExit()) { exitCommand.run(); } else { - macFunctions.ifPresent(JniException.ignore(MacFunctions::transformToAgentApplication)); + macFunctions.map(MacFunctions::uiState).ifPresent(JniException.ignore(MacApplicationUiState::transformToAgentApplication)); mainWindow.close(); this.showTrayNotification(trayIcon); } @@ -195,7 +196,7 @@ class ExitUtil { private void restoreFromTray(ActionEvent event) { Platform.runLater(() -> { - macFunctions.ifPresent(JniException.ignore(MacFunctions::transformToForegroundApplication)); + macFunctions.map(MacFunctions::uiState).ifPresent(JniException.ignore(MacApplicationUiState::transformToForegroundApplication)); mainWindow.show(); mainWindow.requestFocus(); }); diff --git a/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java b/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java index a6c4509de..8e5f60b06 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java +++ b/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java @@ -15,9 +15,10 @@ import java.nio.file.Path; import java.util.concurrent.ExecutionException; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.jni.JniException; +import org.cryptomator.jni.MacApplicationUiState; +import org.cryptomator.jni.MacFunctions; import org.cryptomator.ui.controllers.MainController; -import org.cryptomator.ui.jni.JniException; -import org.cryptomator.ui.jni.MacFunctions; import org.cryptomator.ui.util.ActiveWindowStyleSupport; import org.cryptomator.ui.util.DeferredCloser; import org.cryptomator.ui.util.SingleInstanceManager; @@ -69,7 +70,7 @@ public class MainApplication extends Application { } // show window and start observing its focus: - comp.nativeMacFunctions().ifPresent(JniException.ignore(MacFunctions::transformToForegroundApplication)); + comp.nativeMacFunctions().map(MacFunctions::uiState).ifPresent(JniException.ignore(MacApplicationUiState::transformToForegroundApplication)); primaryStage.show(); ActiveWindowStyleSupport.startObservingFocus(primaryStage); comp.exitUtil().initExitHandler(this::quit); diff --git a/main/ui/src/main/java/org/cryptomator/ui/jni/JniException.java b/main/ui/src/main/java/org/cryptomator/ui/jni/JniException.java deleted file mode 100644 index 2fd06eb07..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/jni/JniException.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.cryptomator.ui.jni; - -import java.util.function.Consumer; - -/** - * Thrown to indicate that a JNI call didn't succeed, i.e. returned an unexpected return value. - */ -public class JniException extends RuntimeException { - - protected JniException(String message) { - super(message); - } - - public static Consumer ignore(Consumer consumer) { - return value -> { - try { - consumer.accept(value); - } catch (RuntimeException e) { - // no-op - } - }; - } - -} diff --git a/main/ui/src/main/java/org/cryptomator/ui/jni/JniModule.java b/main/ui/src/main/java/org/cryptomator/ui/jni/JniModule.java deleted file mode 100644 index de72d0228..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/jni/JniModule.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.cryptomator.ui.jni; - -import java.util.Optional; - -import javax.inject.Singleton; - -import org.apache.commons.lang3.SystemUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import dagger.Module; -import dagger.Provides; - -@Module -public class JniModule { - - private static final Logger LOG = LoggerFactory.getLogger(JniModule.class); - - @Provides - @Singleton - Optional provideMacFunctions(MacFunctions macFunctions) { - if (SystemUtils.IS_OS_MAC) { - try { - System.loadLibrary("MacFunctions"); - return Optional.of(macFunctions); - } catch (UnsatisfiedLinkError e) { - LOG.error("Could not load JNI lib from path {}", System.getProperty("java.library.path")); - } - } - return Optional.empty(); - } - -} diff --git a/main/ui/src/main/java/org/cryptomator/ui/jni/MacFunctions.java b/main/ui/src/main/java/org/cryptomator/ui/jni/MacFunctions.java deleted file mode 100644 index 3cc58d7db..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/jni/MacFunctions.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.cryptomator.ui.jni; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class MacFunctions { - - @Inject - MacFunctions() { - } - - /** - * Makes the current application a foreground application, which appears in the Dock and the Application Switcher. - */ - public void transformToForegroundApplication() { - int errorCode = transformToForegroundApplication0(); - if (errorCode != 0) { - throw new JniException("Failed to make app a foreground app. Error code " + errorCode); - } - } - - private native int transformToForegroundApplication0(); - - /** - * Makes the current application an agent app. Agent apps do not appear in the Dock or in the Force Quit window. - */ - public void transformToAgentApplication() { - int errorCode = transformToAgentApplication0(); - if (errorCode != 0) { - throw new JniException("Failed to make app an agent app. Error code " + errorCode); - } - } - - private native int transformToAgentApplication0(); - -}