mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-21 20:21:27 +00:00
externalized JNI bindings
This commit is contained in:
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user