From bee9c9f452cee022d2206ba7aa76e23b74d73280 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 28 Jun 2022 15:39:04 +0200 Subject: [PATCH] closes #1713 quit application by locking open vaults, if user wished so. --- .../cryptomator/ui/common/VaultService.java | 3 +- .../ui/fxapp/FxApplicationTerminator.java | 28 +++++++++++++++++-- .../cryptomator/ui/quit/QuitController.java | 1 - 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/common/VaultService.java b/src/main/java/org/cryptomator/ui/common/VaultService.java index a6486f35f..8486a09c0 100644 --- a/src/main/java/org/cryptomator/ui/common/VaultService.java +++ b/src/main/java/org/cryptomator/ui/common/VaultService.java @@ -86,7 +86,8 @@ public class VaultService { } /** - * Creates but doesn't start a lock-all task. + * Creates a lock-all task. + * This task itself is _not started_, but its subtasks locking each vault will be already executed. * * @param vaults The list of vaults to be locked * @param forced Whether to attempt a forced lock diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationTerminator.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationTerminator.java index 5b68b5992..cb34ae3d0 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationTerminator.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationTerminator.java @@ -7,6 +7,7 @@ import org.cryptomator.common.vaults.LockNotCompletedException; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultState; import org.cryptomator.common.vaults.Volume; +import org.cryptomator.ui.common.VaultService; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,20 +29,24 @@ import static org.cryptomator.common.vaults.VaultState.Value.*; public class FxApplicationTerminator { private static final Set STATES_ALLOWING_TERMINATION = EnumSet.of(LOCKED, NEEDS_MIGRATION, MISSING, ERROR); + private static final Set STATES_PREVENT_TERMINATION = EnumSet.of(PROCESSING); private static final Logger LOG = LoggerFactory.getLogger(FxApplicationTerminator.class); private final ObservableList vaults; private final ShutdownHook shutdownHook; private final FxApplicationWindows appWindows; private final AtomicBoolean allowQuitWithoutPrompt = new AtomicBoolean(); + private final AtomicBoolean preventQuitWithGracefulLock = new AtomicBoolean(); private final Settings settings; + private final VaultService vaultService; @Inject - public FxApplicationTerminator(ObservableList vaults, ShutdownHook shutdownHook, FxApplicationWindows appWindows, Settings settings) { + public FxApplicationTerminator(ObservableList vaults, ShutdownHook shutdownHook, FxApplicationWindows appWindows, Settings settings, VaultService vaultService) { this.vaults = vaults; this.shutdownHook = shutdownHook; this.appWindows = appWindows; this.settings = settings; + this.vaultService = vaultService; } public void initialize() { @@ -75,6 +80,10 @@ public class FxApplicationTerminator { private void vaultListChanged(@SuppressWarnings("unused") Observable observable) { boolean allowSuddenTermination = vaults.stream().map(Vault::getState).allMatch(STATES_ALLOWING_TERMINATION::contains); boolean stateChanged = allowQuitWithoutPrompt.compareAndSet(!allowSuddenTermination, allowSuddenTermination); + + boolean preventGracefulTermination = vaults.stream().map(Vault::getState).anyMatch(STATES_PREVENT_TERMINATION::contains); + preventQuitWithGracefulLock.set(preventGracefulTermination); + Desktop desktop = Desktop.getDesktop(); if (stateChanged && desktop.isSupported(Desktop.Action.APP_SUDDEN_TERMINATION)) { if (allowSuddenTermination) { @@ -95,8 +104,21 @@ public class FxApplicationTerminator { */ private void handleQuitRequest(@SuppressWarnings("unused") @Nullable EventObject e, QuitResponse response) { var exitingResponse = new ExitingQuitResponse(response); - if (allowQuitWithoutPrompt.get() || settings.autoCloseVaults().get()) { + + if (allowQuitWithoutPrompt.get()) { exitingResponse.performQuit(); + } else if (settings.autoCloseVaults().get() && !preventQuitWithGracefulLock.get()) { + var lockAllTask = vaultService.createLockAllTask(vaults.filtered(Vault::isUnlocked), false); + lockAllTask.setOnSucceeded(event -> { + LOG.info("Locked remaining vaults was succesful."); + exitingResponse.performQuit(); + }); + lockAllTask.setOnFailed(event -> { + LOG.warn("Unable to lock all vaults."); + exitingResponse.cancelQuit(); + //TODO: notify user!?! + }); + lockAllTask.run(); } else { appWindows.showQuitWindow(exitingResponse); } @@ -118,7 +140,7 @@ public class FxApplicationTerminator { /** * A dummy QuitResponse that ignores the response. - * + *

* To be used with {@link #handleQuitRequest(EventObject, QuitResponse)} if the invoking method is not interested in the response. */ private static class NoopQuitResponse implements QuitResponse { diff --git a/src/main/java/org/cryptomator/ui/quit/QuitController.java b/src/main/java/org/cryptomator/ui/quit/QuitController.java index 7be5905d5..207ae42c8 100644 --- a/src/main/java/org/cryptomator/ui/quit/QuitController.java +++ b/src/main/java/org/cryptomator/ui/quit/QuitController.java @@ -1,6 +1,5 @@ package org.cryptomator.ui.quit; -import org.cryptomator.common.settings.Settings; import org.cryptomator.common.vaults.Vault; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.VaultService;