瀏覽代碼

externalized JNI bindings

Sebastian Stenzel 8 年之前
父節點
當前提交
e0ae50378f

+ 10 - 9
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> T initializeLazily(AtomicReference<T> reference, Supplier<T> 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;
+				}
+			});
 		}
 	}
 

+ 5 - 0
main/ui/pom.xml

@@ -54,6 +54,11 @@
 			<groupId>org.cryptomator</groupId>
 			<artifactId>frontend-webdav</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>org.cryptomator</groupId>
+			<artifactId>jni</artifactId>
+			<version>1.0.0-SNAPSHOT</version>
+		</dependency>
 		
 		<!-- EasyBind -->
 		<dependency>

+ 3 - 2
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<MacFunctions> nativeMacFunctions();
-}
+
+}

+ 10 - 2
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<MacFunctions> provideMacFunctions() {
+		return JniModule.macFunctions();
+	}
+
 }

+ 5 - 4
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();
 		});

+ 4 - 3
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);

+ 0 - 24
main/ui/src/main/java/org/cryptomator/ui/jni/JniException.java

@@ -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 <T> Consumer<T> ignore(Consumer<T> consumer) {
-		return value -> {
-			try {
-				consumer.accept(value);
-			} catch (RuntimeException e) {
-				// no-op
-			}
-		};
-	}
-
-}

+ 0 - 33
main/ui/src/main/java/org/cryptomator/ui/jni/JniModule.java

@@ -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<MacFunctions> 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();
-	}
-
-}

+ 0 - 37
main/ui/src/main/java/org/cryptomator/ui/jni/MacFunctions.java

@@ -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();
-
-}