diff --git a/src/main/java/org/cryptomator/ui/fxapp/AutoUnlocker.java b/src/main/java/org/cryptomator/ui/fxapp/AutoUnlocker.java index 973d919fc..410910e47 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/AutoUnlocker.java +++ b/src/main/java/org/cryptomator/ui/fxapp/AutoUnlocker.java @@ -1,30 +1,83 @@ package org.cryptomator.ui.fxapp; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.common.vaults.VaultListManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.collections.ObservableList; +import java.util.Arrays; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; @FxApplicationScoped public class AutoUnlocker { + private static final Logger LOG = LoggerFactory.getLogger(AutoUnlocker.class); + private final ObservableList vaults; private final FxApplicationWindows appWindows; + private final ScheduledExecutorService scheduler; + private ScheduledFuture future; + private boolean isPeriodicCheckActive = false; @Inject - public AutoUnlocker(ObservableList vaults, FxApplicationWindows appWindows) { + public AutoUnlocker(ObservableList vaults, FxApplicationWindows appWindows, ScheduledExecutorService scheduler) { this.vaults = vaults; this.appWindows = appWindows; + this.scheduler = scheduler; } - public void unlock() { - vaults.stream().filter(Vault::isLocked) // - .filter(v -> v.getVaultSettings().unlockAfterStartup().get()) // - .>reduce(CompletableFuture.completedFuture(null), // - (unlockFlow, v) -> unlockFlow.handle((voit, ex) -> appWindows.startUnlockWorkflow(v, null)).thenCompose(stage -> stage), //we don't care here about the exception, logged elsewhere - (unlockChain1, unlockChain2) -> unlockChain1.handle((voit, ex) -> unlockChain2).thenCompose(stage -> stage)); + public void unlockAll() { + unlock(vaults.stream().filter(v -> v.getVaultSettings().unlockAfterStartup().get())); } + public void unlock(Stream vaultStream) { + vaultStream.filter(Vault::isLocked) + .>reduce(CompletableFuture.completedFuture(null), + (unlockFlow, v) -> unlockFlow.handle((voit, ex) -> appWindows.startUnlockWorkflow(v, null)).thenCompose(stage -> stage), // we don't care here about the exception, logged elsewhere + (unlockChain1, unlockChain2) -> unlockChain1.handle((voit, ex) -> unlockChain2).thenCompose(stage -> stage)); + } + + public void startMissingVaultsChecker() { + if (!isPeriodicCheckActive && getMissingAutoUnlockVaults().count() > 0) { + LOG.info("Found MISSING vaults, starting periodic check"); + future = scheduler.scheduleWithFixedDelay(this::tick, 0, 1, TimeUnit.SECONDS); + isPeriodicCheckActive = true; + } + } + + private void tick() { + // Find the vaults that are missing but have an existing directory + Vault[] vaultArray = getMissingAutoUnlockVaults().filter(v -> v.getPath().toFile().isDirectory()).toArray(Vault[]::new); + if (vaultArray.length > 0) { + + // Redetermine vault states + for (Vault v : vaultArray) { + LOG.info("Found vault directory for '{}'", v.getDisplayName()); + VaultListManager.redetermineVaultState(v); + } + + // Unlock the vaults that were previously missing + unlock(Arrays.stream(vaultArray)); + } + + // Stop checking if there are no more missing vaults + if (getMissingAutoUnlockVaults().count() == 0) { + LOG.info("No more MISSING vaults, stopping periodic check"); + isPeriodicCheckActive = false; + future.cancel(false); + } + } + + private Stream getMissingAutoUnlockVaults() { + return vaults.stream() + .filter(Vault::isMissing) + .filter(v -> v.getVaultSettings().unlockAfterStartup().get()); + } } diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 3ddb7cba6..850d2a91e 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -68,7 +68,7 @@ public class FxApplication { }); launchEventHandler.startHandlingLaunchEvents(); - autoUnlocker.unlock(); + autoUnlocker.unlockAll(); + autoUnlocker.startMissingVaultsChecker(); } - }