瀏覽代碼

replaced FUPFMS

with more generic set of used mount services
Sebastian Stenzel 1 年之前
父節點
當前提交
a0fcb63a1a

+ 0 - 9
src/main/java/org/cryptomator/common/CommonsModule.java

@@ -14,7 +14,6 @@ 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.mount.MountService;
 import org.cryptomator.integrations.revealpath.RevealPathService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +29,6 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
 
 @Module(subcomponents = {VaultComponent.class}, includes = {VaultListModule.class, KeychainModule.class, MountModule.class})
 public abstract class CommonsModule {
@@ -134,11 +132,4 @@ public abstract class CommonsModule {
 		LOG.error("Uncaught exception in " + thread.getName(), throwable);
 	}
 
-	@Provides
-	@Singleton
-	@Named("FUPFMS")
-	static AtomicReference<MountService> provideFirstUsedProblematicFuseMountService() {
-		return new AtomicReference<>(null);
-	}
-
 }

+ 11 - 0
src/main/java/org/cryptomator/common/mount/MountModule.java

@@ -6,9 +6,12 @@ import org.cryptomator.common.ObservableUtil;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.integrations.mount.MountService;
 
+import javax.inject.Named;
 import javax.inject.Singleton;
 import javafx.beans.value.ObservableValue;
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 @Module
 public class MountModule {
@@ -28,4 +31,12 @@ public class MountModule {
 				fallbackProvider);
 	}
 
+
+	@Provides
+	@Singleton
+	@Named("usedMountServices")
+	static Set<MountService> provideSetOfUsedMountServices() {
+		return ConcurrentHashMap.newKeySet();
+	}
+
 }

+ 22 - 15
src/main/java/org/cryptomator/common/mount/Mounter.java

@@ -16,7 +16,8 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.Map;
+import java.util.Set;
 
 import static org.cryptomator.integrations.mount.MountCapability.MOUNT_AS_DRIVE_LETTER;
 import static org.cryptomator.integrations.mount.MountCapability.MOUNT_TO_EXISTING_DIR;
@@ -27,12 +28,17 @@ import static org.cryptomator.integrations.mount.MountCapability.UNMOUNT_FORCED;
 @Singleton
 public class Mounter {
 
-	private static final List<String> CONFLICTING_MOUNT_SERVICES = List.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", "org.cryptomator.frontend.fuse.mount.FuseTMountProvider");
+	// mount providers (key) can not be used if any of the conflicting mount providers (values) are already in use
+	private static final Map<String, Set<String>> CONFLICTING_MOUNT_SERVICES = Map.of(
+			"org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", Set.of("org.cryptomator.frontend.fuse.mount.FuseTMountProvider"),
+			"org.cryptomator.frontend.fuse.mount.FuseTMountProvider", Set.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider")
+	);
+
 	private final Environment env;
 	private final Settings settings;
 	private final WindowsDriveLetters driveLetters;
 	private final List<MountService> mountProviders;
-	private final AtomicReference<MountService> firstUsedProblematicFuseMountService;
+	private final Set<MountService> usedMountServices;
 	private final ObservableValue<MountService> defaultMountService;
 
 	@Inject
@@ -40,13 +46,13 @@ public class Mounter {
 				   Settings settings, //
 				   WindowsDriveLetters driveLetters, //
 				   List<MountService> mountProviders, //
-				   @Named("FUPFMS") AtomicReference<MountService> firstUsedProblematicFuseMountService, //
+				   @Named("usedMountServices") Set<MountService> usedMountServices, //
 				   ObservableValue<MountService> defaultMountService) {
 		this.env = env;
 		this.settings = settings;
 		this.driveLetters = driveLetters;
 		this.mountProviders = mountProviders;
-		this.firstUsedProblematicFuseMountService = firstUsedProblematicFuseMountService;
+		this.usedMountServices = usedMountServices;
 		this.defaultMountService = defaultMountService;
 	}
 
@@ -149,23 +155,24 @@ public class Mounter {
 	}
 
 	public MountHandle mount(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException {
-		var selMntServ = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
+		var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
 
-		var targetIsProblematicFuse = isProblematicFuseService(selMntServ);
-		if (targetIsProblematicFuse && firstUsedProblematicFuseMountService.get() == null) {
-			firstUsedProblematicFuseMountService.set(selMntServ);
-		} else if (targetIsProblematicFuse && !firstUsedProblematicFuseMountService.get().equals(selMntServ)) {
+		if (isConflictingMountService(mountService)) {
+			// TODO: neither message displayed in UI nor exception is specific to FUSE, so rename this class
 			throw new FuseRestartRequiredException("Failed to mount the specified mount service.");
 		}
 
-		var builder = selMntServ.forFileSystem(cryptoFsRoot);
-		var internal = new SettledMounter(selMntServ, builder, vaultSettings);
+		usedMountServices.add(mountService);
+
+		var builder = mountService.forFileSystem(cryptoFsRoot);
+		var internal = new SettledMounter(mountService, builder, vaultSettings); // FIXME: no need for an inner class
 		var cleanup = internal.prepare();
-		return new MountHandle(builder.mount(), selMntServ.hasCapability(UNMOUNT_FORCED), cleanup);
+		return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), cleanup);
 	}
 
-	public static boolean isProblematicFuseService(MountService service) {
-		return CONFLICTING_MOUNT_SERVICES.contains(service.getClass().getName());
+	public boolean isConflictingMountService(MountService service) {
+		var conflictingServices = CONFLICTING_MOUNT_SERVICES.getOrDefault(service.getClass().getName(), Set.of());
+		return usedMountServices.stream().map(MountService::getClass).map(Class::getName).anyMatch(conflictingServices::contains);
 	}
 
 	public record MountHandle(Mount mountObj, boolean supportsUnmountForced, Runnable specialCleanup) {

+ 2 - 7
src/main/java/org/cryptomator/ui/vaultoptions/MountOptionsController.java

@@ -38,7 +38,6 @@ import java.util.List;
 import java.util.Optional;
 import java.util.ResourceBundle;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
 
 @VaultOptionsScoped
 public class MountOptionsController implements FxController {
@@ -87,7 +86,7 @@ public class MountOptionsController implements FxController {
 						   FxApplicationWindows applicationWindows, //
 						   Lazy<Application> application, //
 						   List<MountService> mountProviders, //
-						   @Named("FUPFMS") AtomicReference<MountService> firstUsedProblematicFuseMountService, //
+						   Mounter mounter, //
 						   ObservableValue<MountService> defaultMountService) {
 		this.window = window;
 		this.vaultSettings = vault.getVaultSettings();
@@ -99,11 +98,7 @@ public class MountOptionsController implements FxController {
 		this.mountProviders = mountProviders;
 		this.defaultMountService = defaultMountService;
 		this.selectedMountService = Bindings.createObjectBinding(this::reselectMountService, defaultMountService, vaultSettings.mountService);
-		this.fuseRestartRequired = selectedMountService.map(s -> {
-			return firstUsedProblematicFuseMountService.get() != null //
-					&& Mounter.isProblematicFuseService(s) //
-					&& !firstUsedProblematicFuseMountService.get().equals(s);
-		});
+		this.fuseRestartRequired = selectedMountService.map(mounter::isConflictingMountService);
 
 		this.defaultMountFlags = selectedMountService.map(s -> {
 			if (s.hasCapability(MountCapability.MOUNT_FLAGS)) {