use quick access service in unlock/lock

This commit is contained in:
Armin Schrenk
2024-06-20 23:05:44 +02:00
parent 4114ea6163
commit e5003c1783
9 changed files with 79 additions and 8 deletions

View File

@@ -14,6 +14,7 @@ import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.common.vaults.VaultComponent;
import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.integrations.quickaccess.QuickAccessService;
import org.cryptomator.integrations.revealpath.RevealPathService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -128,6 +129,12 @@ public abstract class CommonsModule {
return executorService;
}
@Provides
@Singleton
static Optional<QuickAccessService> provideQuickAccessService() {
return QuickAccessService.get().findFirst();
}
private static void handleUncaughtExceptionInBackgroundThread(Thread thread, Throwable throwable) {
LOG.error("Uncaught exception in " + thread.getName(), throwable);
}

View File

@@ -41,6 +41,7 @@ public class Settings {
static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
static final boolean DEFAULT_DEBUG_MODE = false;
static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
static final boolean DEFAULT_ADD_TO_QUICK_ACCESS = true;
@Deprecated // to be changed to "whatever is available" eventually
static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name();
@@ -52,6 +53,7 @@ public class Settings {
public final BooleanProperty startHidden;
public final BooleanProperty autoCloseVaults;
public final BooleanProperty useKeychain;
public final BooleanProperty addToQuickAccess; //TODO: for now, we only support Sidebar integration per System (GNOME Nautilus for Linux)
public final IntegerProperty port;
public final IntegerProperty numTrayNotifications;
public final BooleanProperty debugMode;
@@ -89,6 +91,7 @@ public class Settings {
this.startHidden = new SimpleBooleanProperty(this, "startHidden", json.startHidden);
this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults);
this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain);
this.addToQuickAccess = new SimpleBooleanProperty(this, "addToQuickAccess", json.addToQuickAccess);
this.port = new SimpleIntegerProperty(this, "webDavPort", json.port);
this.numTrayNotifications = new SimpleIntegerProperty(this, "numTrayNotifications", json.numTrayNotifications);
this.debugMode = new SimpleBooleanProperty(this, "debugMode", json.debugMode);
@@ -116,6 +119,7 @@ public class Settings {
startHidden.addListener(this::somethingChanged);
autoCloseVaults.addListener(this::somethingChanged);
useKeychain.addListener(this::somethingChanged);
addToQuickAccess.addListener(this::somethingChanged);
port.addListener(this::somethingChanged);
numTrayNotifications.addListener(this::somethingChanged);
debugMode.addListener(this::somethingChanged);
@@ -170,6 +174,7 @@ public class Settings {
json.startHidden = startHidden.get();
json.autoCloseVaults = autoCloseVaults.get();
json.useKeychain = useKeychain.get();
json.addToQuickAccess = addToQuickAccess.get();
json.port = port.get();
json.numTrayNotifications = numTrayNotifications.get();
json.debugMode = debugMode.get();

View File

@@ -86,4 +86,6 @@ class SettingsJson {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP;
@JsonProperty("addToQuickAccess")
boolean addToQuickAccess = Settings.DEFAULT_ADD_TO_QUICK_ACCESS;
}

View File

@@ -11,6 +11,7 @@ package org.cryptomator.common.vaults;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Constants;
import org.cryptomator.common.mount.Mounter;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
@@ -23,6 +24,9 @@ import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.cryptomator.integrations.mount.MountFailedException;
import org.cryptomator.integrations.mount.Mountpoint;
import org.cryptomator.integrations.mount.UnmountFailedException;
import org.cryptomator.integrations.quickaccess.QuickAccessService;
import org.cryptomator.integrations.quickaccess.QuickAccessServiceException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,6 +46,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@@ -54,6 +59,7 @@ public class Vault {
private final VaultSettings vaultSettings;
private final AtomicReference<CryptoFileSystem> cryptoFileSystem;
private final AtomicReference<QuickAccessService.QuickAccessEntry> quickAccessEntry;
private final VaultState state;
private final ObjectProperty<Exception> lastKnownException;
private final VaultConfigCache configCache;
@@ -67,6 +73,8 @@ public class Vault {
private final BooleanBinding unknownError;
private final ObjectBinding<Mountpoint> mountPoint;
private final Mounter mounter;
private final Settings settings;
private final Optional<QuickAccessService> quickAccessService;
private final BooleanProperty showingStats;
private final AtomicReference<Mounter.MountHandle> mountHandle = new AtomicReference<>(null);
@@ -78,7 +86,7 @@ public class Vault {
VaultState state, //
@Named("lastKnownException") ObjectProperty<Exception> lastKnownException, //
VaultStats stats, //
Mounter mounter) {
Mounter mounter, Settings settings, Optional<QuickAccessService> quickAccessService) {
this.vaultSettings = vaultSettings;
this.configCache = configCache;
this.cryptoFileSystem = cryptoFileSystem;
@@ -94,7 +102,10 @@ public class Vault {
this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state);
this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
this.mounter = mounter;
this.settings = settings;
this.quickAccessService = quickAccessService;
this.showingStats = new SimpleBooleanProperty(false);
this.quickAccessEntry = new AtomicReference<>(null);
}
// ******************************************************************************
@@ -154,6 +165,9 @@ public class Vault {
var rootPath = fs.getRootDirectories().iterator().next();
var mountHandle = mounter.mount(vaultSettings, rootPath);
success = this.mountHandle.compareAndSet(null, mountHandle);
if (settings.addToQuickAccess.getValue()) {
addToQuickAccess();
}
} finally {
if (!success) {
destroyCryptoFileSystem();
@@ -178,6 +192,7 @@ public class Vault {
mountHandle.mountObj().close();
mountHandle.specialCleanup().run();
} finally {
removeFromSidebar();
destroyCryptoFileSystem();
}
@@ -185,6 +200,48 @@ public class Vault {
LOG.info("Locked vault '{}'", getDisplayName());
}
private synchronized void addToQuickAccess() {
if (quickAccessEntry.get() != null) {
//we don't throw an exception since we don't wanna block unlocking
LOG.warn("Vault already added to quick access area. Will be removed on next lock operation.");
return;
}
quickAccessService.ifPresentOrElse( //
this::addToQuickAccessInternal, //
() -> LOG.warn("Unable to add Vault to quick access area: No implementation available."));
}
private void addToQuickAccessInternal(@NotNull QuickAccessService s) {
if (getMountPoint() instanceof Mountpoint.WithPath mp) {
try {
var entry = s.add(mp.path(), getDisplayName());
quickAccessEntry.set(entry);
} catch (QuickAccessServiceException e) {
LOG.error("Adding vault to quick access area failed", e);
}
} else {
LOG.warn("Unable to add vault to quick access area: Vault is not mounted to local system path.");
}
}
private synchronized void removeFromSidebar() {
if (quickAccessEntry.get() == null) {
LOG.info("Removing vault from quick access area: Entry not found, nothing to do.");
return;
}
removeFromSidebarInternal();
}
private void removeFromSidebarInternal() {
try {
quickAccessEntry.get().remove();
quickAccessEntry.set(null);
} catch (QuickAccessServiceException e) {
LOG.error("Removing vault from quick access area failed", e);
}
}
// ******************************************************************************
// Observable Properties
// *******************************************************************************