|
@@ -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
|
|
|
// *******************************************************************************
|