From a404740cebf43d7ee1f2b2c46a5497cd0b49cc8d Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 7 Mar 2022 17:35:48 +0100 Subject: [PATCH 1/9] Updated to integrations-api 1.1.0-beta2 --- pom.xml | 8 +- src/main/java/module-info.java | 11 +- .../cryptomator/common/PluginClassLoader.java | 1 + .../common/keychain/KeychainManager.java | 10 +- .../common/keychain/KeychainModule.java | 22 +--- .../ui/launcher/UiLauncherModule.java | 13 +- .../GeneralPreferencesController.java | 9 +- .../ui/traymenu/AwtTrayMenuController.java | 72 +++++++++++ .../ui/traymenu/TrayIconController.java | 51 -------- .../ui/traymenu/TrayImageFactory.java | 35 ------ .../ui/traymenu/TrayMenuComponent.java | 21 ++-- .../ui/traymenu/TrayMenuController.java | 119 +++++++++--------- .../ui/traymenu/TrayMenuModule.java | 18 +++ 13 files changed, 195 insertions(+), 195 deletions(-) create mode 100644 src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java delete mode 100644 src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java delete mode 100644 src/main/java/org/cryptomator/ui/traymenu/TrayImageFactory.java create mode 100644 src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java diff --git a/pom.xml b/pom.xml index 8975b8693..2c18c2170 100644 --- a/pom.xml +++ b/pom.xml @@ -28,10 +28,10 @@ 2.3.1 - 1.1.0-beta1 - 1.0.0 - 1.0.0 - 1.0.1 + 1.1.0-beta2 + 1.1.0-beta1 + 1.1.0-beta1 + 1.1.0-beta1 1.3.3 1.3.3 1.2.6 diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index f13308be5..a8d85c27f 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,7 +1,5 @@ -import org.cryptomator.integrations.autostart.AutoStartProvider; -import org.cryptomator.integrations.keychain.KeychainAccessProvider; -import org.cryptomator.integrations.tray.TrayIntegrationProvider; -import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; +import org.cryptomator.integrations.tray.TrayMenuController; +import org.cryptomator.ui.traymenu.AwtTrayMenuController; module org.cryptomator.desktop { requires org.cryptomator.cryptofs; @@ -29,10 +27,7 @@ module org.cryptomator.desktop { requires logback.classic; requires logback.core; - uses AutoStartProvider; - uses KeychainAccessProvider; - uses TrayIntegrationProvider; - uses UiAppearanceProvider; + provides TrayMenuController with AwtTrayMenuController; opens org.cryptomator.common.settings to com.google.gson; diff --git a/src/main/java/org/cryptomator/common/PluginClassLoader.java b/src/main/java/org/cryptomator/common/PluginClassLoader.java index 16932923b..28c73cd2c 100644 --- a/src/main/java/org/cryptomator/common/PluginClassLoader.java +++ b/src/main/java/org/cryptomator/common/PluginClassLoader.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +@Deprecated // to be moved to integrations-api 1.1.0 @Singleton public class PluginClassLoader extends URLClassLoader { diff --git a/src/main/java/org/cryptomator/common/keychain/KeychainManager.java b/src/main/java/org/cryptomator/common/keychain/KeychainManager.java index d6adadfe4..e0269348a 100644 --- a/src/main/java/org/cryptomator/common/keychain/KeychainManager.java +++ b/src/main/java/org/cryptomator/common/keychain/KeychainManager.java @@ -44,9 +44,9 @@ public class KeychainManager implements KeychainAccessProvider { } @Override + @Deprecated public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException { - getKeychainOrFail().storePassphrase(key, passphrase); - setPassphraseStored(key, true); + storePassphrase(key, null, passphrase); } @Override @@ -69,11 +69,9 @@ public class KeychainManager implements KeychainAccessProvider { } @Override + @Deprecated public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException { - if (isPassphraseStored(key)) { - getKeychainOrFail().changePassphrase(key, passphrase); - setPassphraseStored(key, true); - } + changePassphrase(key, null, passphrase); } @Override diff --git a/src/main/java/org/cryptomator/common/keychain/KeychainModule.java b/src/main/java/org/cryptomator/common/keychain/KeychainModule.java index 6356c4966..63749b445 100644 --- a/src/main/java/org/cryptomator/common/keychain/KeychainModule.java +++ b/src/main/java/org/cryptomator/common/keychain/KeychainModule.java @@ -2,42 +2,30 @@ package org.cryptomator.common.keychain; import dagger.Module; import dagger.Provides; -import org.cryptomator.common.PluginClassLoader; import org.cryptomator.common.settings.Settings; import org.cryptomator.integrations.keychain.KeychainAccessProvider; import javax.inject.Singleton; import javafx.beans.binding.Bindings; import javafx.beans.binding.ObjectExpression; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.List; @Module public class KeychainModule { @Provides @Singleton - static Set> provideAvailableKeychainAccessProviderFactories(PluginClassLoader classLoader) { - return ServiceLoader.load(KeychainAccessProvider.class, classLoader).stream().collect(Collectors.toUnmodifiableSet()); + static List provideSupportedKeychainAccessProviders() { + return KeychainAccessProvider.get().toList(); } @Provides @Singleton - static Set provideSupportedKeychainAccessProviders(Set> availableFactories) { - return availableFactories.stream() // - .map(ServiceLoader.Provider::get) // - .filter(KeychainAccessProvider::isSupported) // - .collect(Collectors.toUnmodifiableSet()); - } - - @Provides - @Singleton - static ObjectExpression provideKeychainAccessProvider(Settings settings, Set providers) { + static ObjectExpression provideKeychainAccessProvider(Settings settings, List providers) { return Bindings.createObjectBinding(() -> { var selectedProviderClass = settings.keychainProvider().get(); var selectedProvider = providers.stream().filter(provider -> provider.getClass().getName().equals(selectedProviderClass)).findAny(); - var fallbackProvider = providers.stream().findAny().orElse(null); + var fallbackProvider = providers.stream().findFirst().orElse(null); return selectedProvider.orElse(fallbackProvider); }, settings.keychainProvider()); } diff --git a/src/main/java/org/cryptomator/ui/launcher/UiLauncherModule.java b/src/main/java/org/cryptomator/ui/launcher/UiLauncherModule.java index c30efa30e..64b05bdab 100644 --- a/src/main/java/org/cryptomator/ui/launcher/UiLauncherModule.java +++ b/src/main/java/org/cryptomator/ui/launcher/UiLauncherModule.java @@ -34,21 +34,20 @@ public abstract class UiLauncherModule { @Provides @Singleton - static Optional provideAppearanceProvider(PluginClassLoader classLoader) { - return ServiceLoader.load(UiAppearanceProvider.class, classLoader).findFirst(); + static Optional provideAppearanceProvider() { + return UiAppearanceProvider.get(); } @Provides @Singleton - static Optional provideAutostartProvider(PluginClassLoader classLoader) { - return ServiceLoader.load(AutoStartProvider.class, classLoader).findFirst(); + static Optional provideAutostartProvider() { + return AutoStartProvider.get(); } - @Provides @Singleton - static Optional provideTrayIntegrationProvider(PluginClassLoader classLoader) { - return ServiceLoader.load(TrayIntegrationProvider.class, classLoader).findFirst(); + static Optional provideTrayIntegrationProvider() { + return TrayIntegrationProvider.get(); } @Provides diff --git a/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java index fafea3f2f..424134a3e 100644 --- a/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java @@ -27,6 +27,7 @@ import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.stage.Stage; import javafx.util.StringConverter; +import java.util.List; import java.util.Optional; import java.util.ResourceBundle; import java.util.Set; @@ -46,7 +47,7 @@ public class GeneralPreferencesController implements FxController { private final ResourceBundle resourceBundle; private final Application application; private final Environment environment; - private final Set keychainAccessProviders; + private final List keychainAccessProviders; private final ErrorComponent.Builder errorComponent; public ChoiceBox themeChoiceBox; public ChoiceBox keychainBackendChoiceBox; @@ -61,7 +62,7 @@ public class GeneralPreferencesController implements FxController { @Inject - GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, TrayMenuComponent trayMenu, Optional autoStartProvider, Set keychainAccessProviders, ObjectProperty selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle, Application application, Environment environment, ErrorComponent.Builder errorComponent) { + GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, TrayMenuComponent trayMenu, Optional autoStartProvider, List keychainAccessProviders, ObjectProperty selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle, Application application, Environment environment, ErrorComponent.Builder errorComponent) { this.window = window; this.settings = settings; this.trayMenuInitialized = trayMenu.isInitialized(); @@ -204,9 +205,9 @@ public class GeneralPreferencesController implements FxController { private static class KeychainProviderClassNameConverter extends StringConverter { - private final Set keychainAccessProviders; + private final List keychainAccessProviders; - public KeychainProviderClassNameConverter(Set keychainAccessProviders) { + public KeychainProviderClassNameConverter(List keychainAccessProviders) { this.keychainAccessProviders = keychainAccessProviders; } diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java new file mode 100644 index 000000000..7c1a0998b --- /dev/null +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -0,0 +1,72 @@ +package org.cryptomator.ui.traymenu; + +import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.integrations.common.Priority; +import org.cryptomator.integrations.tray.ActionItem; +import org.cryptomator.integrations.tray.SeparatorItem; +import org.cryptomator.integrations.tray.SubMenuItem; +import org.cryptomator.integrations.tray.TrayMenuItem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.AWTException; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.SystemTray; +import java.awt.Toolkit; +import java.awt.TrayIcon; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +@Priority(Priority.FALLBACK) +public class AwtTrayMenuController implements org.cryptomator.integrations.tray.TrayMenuController { + + private static final Logger LOG = LoggerFactory.getLogger(AwtTrayMenuController.class); + + private TrayIcon trayIcon; + private PopupMenu menu = new PopupMenu(); + + @Override + public void showTrayIcon(InputStream rawImageData, Runnable defaultAction, String tooltip) throws IOException { + var image = Toolkit.getDefaultToolkit().createImage(rawImageData.readAllBytes()); + trayIcon = new TrayIcon(image, tooltip, menu); + + trayIcon.setImageAutoSize(true); + if (SystemUtils.IS_OS_WINDOWS) { + trayIcon.addActionListener(evt -> defaultAction.run()); + } + + try { + SystemTray.getSystemTray().add(trayIcon); + LOG.debug("initialized tray icon"); + } catch (AWTException e) { + LOG.error("Error adding tray icon", e); + } + } + + @Override + public void updateTrayMenu(List items) { + menu.removeAll(); + addChildren(menu, items); + } + + private void addChildren(Menu menu, List items) { + for (var item : items) { + // TODO: use Pattern Matching for switch, once available + if (item instanceof ActionItem a) { + var menuItem = new MenuItem(a.title()); + menuItem.addActionListener(evt -> a.action().run()); + menu.add(menuItem); + } else if (item instanceof SeparatorItem) { + menu.addSeparator(); + } else if (item instanceof SubMenuItem s) { + var submenu = new Menu(s.title()); + addChildren(submenu, s.items()); + menu.add(submenu); + } + } + } + +} diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java b/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java deleted file mode 100644 index 2c176df76..000000000 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.cryptomator.ui.traymenu; - -import com.google.common.base.Preconditions; -import org.apache.commons.lang3.SystemUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.inject.Inject; -import java.awt.AWTException; -import java.awt.SystemTray; -import java.awt.TrayIcon; - -@TrayMenuScoped -public class TrayIconController { - - private static final Logger LOG = LoggerFactory.getLogger(TrayIconController.class); - - private final TrayMenuController trayMenuController; - private final TrayIcon trayIcon; - private volatile boolean initialized; - - @Inject - TrayIconController(TrayImageFactory imageFactory, TrayMenuController trayMenuController) { - this.trayMenuController = trayMenuController; - this.trayIcon = new TrayIcon(imageFactory.loadImage(), "Cryptomator", trayMenuController.getMenu()); - } - - public synchronized void initializeTrayIcon() throws IllegalStateException { - Preconditions.checkState(!initialized); - - trayIcon.setImageAutoSize(true); - if (SystemUtils.IS_OS_WINDOWS) { - trayIcon.addActionListener(trayMenuController::showMainWindow); - } - - try { - SystemTray.getSystemTray().add(trayIcon); - LOG.debug("initialized tray icon"); - } catch (AWTException e) { - LOG.error("Error adding tray icon", e); - } - - trayMenuController.initTrayMenu(); - - this.initialized = true; - } - - public boolean isInitialized() { - return initialized; - } -} diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayImageFactory.java b/src/main/java/org/cryptomator/ui/traymenu/TrayImageFactory.java deleted file mode 100644 index aa55ca766..000000000 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayImageFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.cryptomator.ui.traymenu; - -import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.integrations.uiappearance.Theme; -import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; - -import javax.inject.Inject; -import java.awt.Image; -import java.awt.Toolkit; -import java.util.Optional; - -@TrayMenuScoped -class TrayImageFactory { - - private final Optional appearanceProvider; - - @Inject - TrayImageFactory(Optional appearanceProvider) { - this.appearanceProvider = appearanceProvider; - } - - public Image loadImage() { - String resourceName = SystemUtils.IS_OS_MAC_OSX ? getMacResourceName() : getWinOrLinuxResourceName(); - return Toolkit.getDefaultToolkit().getImage(getClass().getResource(resourceName)); - } - - private String getMacResourceName() { - return "/img/tray_icon_mac.png"; - } - - private String getWinOrLinuxResourceName() { - return "/img/tray_icon.png"; - } - -} diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java index c4cbfd456..e50269007 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java @@ -5,28 +5,34 @@ *******************************************************************************/ package org.cryptomator.ui.traymenu; -import dagger.Lazy; +import com.google.common.base.Preconditions; import dagger.Subcomponent; +import org.cryptomator.integrations.tray.TrayMenuController; + import java.awt.SystemTray; +import java.util.Optional; @TrayMenuScoped -@Subcomponent +@Subcomponent(modules = {TrayMenuModule.class}) public interface TrayMenuComponent { - Lazy trayIconController(); + Optional trayMenuController(); + + org.cryptomator.ui.traymenu.TrayMenuController trayMenuController2(); // TODO tmp name /** * @return true if a tray icon can be installed */ default boolean isSupported() { - return SystemTray.isSupported(); + // TODO add isSupported to API and move SystemTray.isSupported() to impl + return trayMenuController().isPresent() && SystemTray.isSupported(); } /** * @return true if a tray icon has been installed */ default boolean isInitialized() { - return isSupported() && trayIconController().get().isInitialized(); + return isSupported() && trayMenuController2().isInitialized(); } /** @@ -35,8 +41,9 @@ public interface TrayMenuComponent { * @throws IllegalStateException If already added */ default void initializeTrayIcon() throws IllegalStateException { - assert isSupported(); - trayIconController().get().initializeTrayIcon(); + Preconditions.checkState(isSupported(), "system tray not supported"); + + trayMenuController2().initTrayMenu(); } @Subcomponent.Builder diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java index 4ce3808c4..8189406d2 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java @@ -1,6 +1,12 @@ package org.cryptomator.ui.traymenu; +import com.google.common.base.Preconditions; +import org.apache.commons.lang3.SystemUtils; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.integrations.tray.ActionItem; +import org.cryptomator.integrations.tray.SeparatorItem; +import org.cryptomator.integrations.tray.SubMenuItem; +import org.cryptomator.integrations.tray.TrayMenuItem; import org.cryptomator.ui.fxapp.FxApplication; import org.cryptomator.ui.launcher.AppLifecycleListener; import org.cryptomator.ui.launcher.FxApplicationStarter; @@ -10,44 +16,61 @@ import javax.inject.Inject; import javafx.application.Platform; import javafx.beans.Observable; import javafx.collections.ObservableList; -import java.awt.Menu; -import java.awt.MenuItem; -import java.awt.PopupMenu; -import java.awt.event.ActionEvent; +import java.awt.Image; +import java.awt.Toolkit; import java.awt.event.ActionListener; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.ArrayList; import java.util.EventObject; +import java.util.List; import java.util.Optional; import java.util.ResourceBundle; import java.util.function.Consumer; @TrayMenuScoped -class TrayMenuController { +public class TrayMenuController { + + private static final String TRAY_ICON_MAC = "/img/tray_icon_mac.png"; + private static final String TRAY_ICON = "/img/tray_icon.png"; private final ResourceBundle resourceBundle; private final AppLifecycleListener appLifecycle; private final FxApplicationStarter fxApplicationStarter; private final ObservableList vaults; - private final PopupMenu menu; + private final org.cryptomator.integrations.tray.TrayMenuController trayMenu; + + private volatile boolean initialized; @Inject - TrayMenuController(ResourceBundle resourceBundle, AppLifecycleListener appLifecycle, FxApplicationStarter fxApplicationStarter, ObservableList vaults) { + TrayMenuController(ResourceBundle resourceBundle, AppLifecycleListener appLifecycle, FxApplicationStarter fxApplicationStarter, ObservableList vaults, Optional trayMenu) { this.resourceBundle = resourceBundle; this.appLifecycle = appLifecycle; this.fxApplicationStarter = fxApplicationStarter; this.vaults = vaults; - this.menu = new PopupMenu(); + this.trayMenu = trayMenu.orElse(null); } - public PopupMenu getMenu() { - return menu; - } + public synchronized void initTrayMenu() { + Preconditions.checkState(!initialized, "tray icon already initialized"); - public void initTrayMenu() { vaults.addListener(this::vaultListChanged); vaults.forEach(v -> { v.displayNameProperty().addListener(this::vaultListChanged); }); rebuildMenu(); + + try (var image = getClass().getResourceAsStream(SystemUtils.IS_OS_MAC_OSX ? TRAY_ICON_MAC : TRAY_ICON)) { + trayMenu.showTrayIcon(image, this::showMainWindow, "Cryptomator"); + } catch (IOException e) { + throw new UncheckedIOException("Failed to load embedded resource", e); + } + + initialized = true; + } + + public boolean isInitialized() { + return initialized; } private void vaultListChanged(@SuppressWarnings("unused") Observable observable) { @@ -56,58 +79,42 @@ class TrayMenuController { } private void rebuildMenu() { - menu.removeAll(); + List menu = new ArrayList<>(); - MenuItem showMainWindowItem = new MenuItem(resourceBundle.getString("traymenu.showMainWindow")); - showMainWindowItem.addActionListener(this::showMainWindow); - menu.add(showMainWindowItem); - - MenuItem showPreferencesItem = new MenuItem(resourceBundle.getString("traymenu.showPreferencesWindow")); - showPreferencesItem.addActionListener(this::showPreferencesWindow); - menu.add(showPreferencesItem); - - menu.addSeparator(); - for (Vault v : vaults) { - MenuItem submenu = buildSubmenu(v); - menu.add(submenu); + menu.add(new ActionItem(resourceBundle.getString("traymenu.showMainWindow"), this::showMainWindow)); + menu.add(new ActionItem(resourceBundle.getString("traymenu.showPreferencesWindow"), this::showPreferencesWindow)); + menu.add(new SeparatorItem()); + for (Vault vault : vaults) { + List submenu = buildSubmenu(vault); + menu.add(new SubMenuItem(vault.getDisplayName(), submenu)); } - menu.addSeparator(); + menu.add(new SeparatorItem()); + menu.add(new ActionItem(resourceBundle.getString("traymenu.lockAllVaults"), this::lockAllVaults)); + menu.add(new ActionItem(resourceBundle.getString("traymenu.quitApplication"), this::quitApplication)); +// lockAllItem.setEnabled(!vaults.filtered(Vault::isUnlocked).isEmpty()); - MenuItem lockAllItem = new MenuItem(resourceBundle.getString("traymenu.lockAllVaults")); - lockAllItem.addActionListener(this::lockAllVaults); - lockAllItem.setEnabled(!vaults.filtered(Vault::isUnlocked).isEmpty()); - menu.add(lockAllItem); - - MenuItem quitApplicationItem = new MenuItem(resourceBundle.getString("traymenu.quitApplication")); - quitApplicationItem.addActionListener(this::quitApplication); - menu.add(quitApplicationItem); + trayMenu.updateTrayMenu(menu); } - private Menu buildSubmenu(Vault vault) { - Menu submenu = new Menu(vault.getDisplayName()); - + private List buildSubmenu(Vault vault) { if (vault.isLocked()) { - MenuItem unlockItem = new MenuItem(resourceBundle.getString("traymenu.vault.unlock")); - unlockItem.addActionListener(createActionListenerForVault(vault, this::unlockVault)); - submenu.add(unlockItem); + return List.of( + new ActionItem(resourceBundle.getString("traymenu.vault.unlock"), () -> this.unlockVault(vault)) + ); } else if (vault.isUnlocked()) { - MenuItem lockItem = new MenuItem(resourceBundle.getString("traymenu.vault.lock")); - lockItem.addActionListener(createActionListenerForVault(vault, this::lockVault)); - submenu.add(lockItem); + return List.of( + new ActionItem(resourceBundle.getString("traymenu.vault.lock"), () -> this.lockVault(vault)), + new ActionItem(resourceBundle.getString("traymenu.vault.reveal"), () -> this.revealVault(vault)) - MenuItem revealItem = new MenuItem(resourceBundle.getString("traymenu.vault.reveal")); - revealItem.addActionListener(createActionListenerForVault(vault, this::revealVault)); - submenu.add(revealItem); + ); + } else { + return List.of(); } - - return submenu; } - private ActionListener createActionListenerForVault(Vault vault, Consumer consumer) { - return actionEvent -> consumer.accept(vault); - } + /* action listeners: */ - private void quitApplication(EventObject actionEvent) { + private void quitApplication() { appLifecycle.quit(); } @@ -119,7 +126,7 @@ class TrayMenuController { showMainAppAndThen(app -> app.startLockWorkflow(vault, Optional.empty())); } - private void lockAllVaults(ActionEvent actionEvent) { + private void lockAllVaults() { showMainAppAndThen(app -> app.getVaultService().lockAll(vaults.filtered(Vault::isUnlocked), false)); } @@ -127,11 +134,11 @@ class TrayMenuController { showMainAppAndThen(app -> app.getVaultService().reveal(vault)); } - void showMainWindow(@SuppressWarnings("unused") ActionEvent actionEvent) { - showMainAppAndThen(app -> app.showMainWindow()); + void showMainWindow() { + showMainAppAndThen(FxApplication::showMainWindow); } - private void showPreferencesWindow(@SuppressWarnings("unused") EventObject actionEvent) { + private void showPreferencesWindow() { showMainAppAndThen(app -> app.showPreferencesWindow(SelectedPreferencesTab.ANY)); } diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java new file mode 100644 index 000000000..3110be883 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java @@ -0,0 +1,18 @@ +package org.cryptomator.ui.traymenu; + +import dagger.Module; +import dagger.Provides; +import org.cryptomator.integrations.tray.TrayMenuController; + +import java.util.Optional; + +@Module +public class TrayMenuModule { + + @Provides + @TrayMenuScoped + static Optional provideSupportedKeychainAccessProviders() { + return TrayMenuController.get(); + } + +} From ad6d5bfae93aa9516060df750417ce55627bee3c Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 7 Mar 2022 17:42:56 +0100 Subject: [PATCH 2/9] resolved class name conflict --- .../ui/traymenu/AwtTrayMenuController.java | 4 +++- .../{TrayMenuController.java => TrayMenuBuilder.java} | 11 ++++------- .../cryptomator/ui/traymenu/TrayMenuComponent.java | 7 +++---- 3 files changed, 10 insertions(+), 12 deletions(-) rename src/main/java/org/cryptomator/ui/traymenu/{TrayMenuController.java => TrayMenuBuilder.java} (90%) diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index 7c1a0998b..034847913 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -5,6 +5,7 @@ import org.cryptomator.integrations.common.Priority; import org.cryptomator.integrations.tray.ActionItem; import org.cryptomator.integrations.tray.SeparatorItem; import org.cryptomator.integrations.tray.SubMenuItem; +import org.cryptomator.integrations.tray.TrayMenuController; import org.cryptomator.integrations.tray.TrayMenuItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,7 +22,7 @@ import java.io.InputStream; import java.util.List; @Priority(Priority.FALLBACK) -public class AwtTrayMenuController implements org.cryptomator.integrations.tray.TrayMenuController { +public class AwtTrayMenuController implements TrayMenuController { private static final Logger LOG = LoggerFactory.getLogger(AwtTrayMenuController.class); @@ -58,6 +59,7 @@ public class AwtTrayMenuController implements org.cryptomator.integrations.tray. if (item instanceof ActionItem a) { var menuItem = new MenuItem(a.title()); menuItem.addActionListener(evt -> a.action().run()); + // TODO menuItem.setEnabled(a.enabled()); menu.add(menuItem); } else if (item instanceof SeparatorItem) { menu.addSeparator(); diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java similarity index 90% rename from src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java rename to src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index 8189406d2..5a83c77c2 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -6,6 +6,7 @@ import org.cryptomator.common.vaults.Vault; import org.cryptomator.integrations.tray.ActionItem; import org.cryptomator.integrations.tray.SeparatorItem; import org.cryptomator.integrations.tray.SubMenuItem; +import org.cryptomator.integrations.tray.TrayMenuController; import org.cryptomator.integrations.tray.TrayMenuItem; import org.cryptomator.ui.fxapp.FxApplication; import org.cryptomator.ui.launcher.AppLifecycleListener; @@ -16,20 +17,16 @@ import javax.inject.Inject; import javafx.application.Platform; import javafx.beans.Observable; import javafx.collections.ObservableList; -import java.awt.Image; -import java.awt.Toolkit; -import java.awt.event.ActionListener; import java.io.IOException; import java.io.UncheckedIOException; import java.util.ArrayList; -import java.util.EventObject; import java.util.List; import java.util.Optional; import java.util.ResourceBundle; import java.util.function.Consumer; @TrayMenuScoped -public class TrayMenuController { +public class TrayMenuBuilder { private static final String TRAY_ICON_MAC = "/img/tray_icon_mac.png"; private static final String TRAY_ICON = "/img/tray_icon.png"; @@ -38,12 +35,12 @@ public class TrayMenuController { private final AppLifecycleListener appLifecycle; private final FxApplicationStarter fxApplicationStarter; private final ObservableList vaults; - private final org.cryptomator.integrations.tray.TrayMenuController trayMenu; + private final TrayMenuController trayMenu; private volatile boolean initialized; @Inject - TrayMenuController(ResourceBundle resourceBundle, AppLifecycleListener appLifecycle, FxApplicationStarter fxApplicationStarter, ObservableList vaults, Optional trayMenu) { + TrayMenuBuilder(ResourceBundle resourceBundle, AppLifecycleListener appLifecycle, FxApplicationStarter fxApplicationStarter, ObservableList vaults, Optional trayMenu) { this.resourceBundle = resourceBundle; this.appLifecycle = appLifecycle; this.fxApplicationStarter = fxApplicationStarter; diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java index e50269007..61861e12c 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java @@ -18,7 +18,7 @@ public interface TrayMenuComponent { Optional trayMenuController(); - org.cryptomator.ui.traymenu.TrayMenuController trayMenuController2(); // TODO tmp name + TrayMenuBuilder trayMenuBuilder(); /** * @return true if a tray icon can be installed @@ -32,7 +32,7 @@ public interface TrayMenuComponent { * @return true if a tray icon has been installed */ default boolean isInitialized() { - return isSupported() && trayMenuController2().isInitialized(); + return isSupported() && trayMenuBuilder().isInitialized(); } /** @@ -42,8 +42,7 @@ public interface TrayMenuComponent { */ default void initializeTrayIcon() throws IllegalStateException { Preconditions.checkState(isSupported(), "system tray not supported"); - - trayMenuController2().initTrayMenu(); + trayMenuBuilder().initTrayMenu(); } @Subcomponent.Builder From d7da78fc07bf46fd6a07cee4eefa14ba8a9cd7b4 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sun, 3 Apr 2022 15:26:04 +0200 Subject: [PATCH 3/9] adjust to latest API --- pom.xml | 2 +- src/main/java/module-info.java | 1 + .../cryptomator/ui/fxapp/FxApplication.java | 2 +- .../ui/traymenu/AwtTrayMenuController.java | 19 +++++++++++----- .../ui/traymenu/TrayMenuBuilder.java | 22 +++++++++++++------ .../ui/traymenu/TrayMenuComponent.java | 9 ++++---- 6 files changed, 36 insertions(+), 19 deletions(-) diff --git a/pom.xml b/pom.xml index 51203f0e5..98994551d 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 2.4.0 - 1.1.0-beta2 + 1.1.0-beta3 1.1.0-beta1 1.1.0-beta1 1.1.0-beta1 diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index e8ee1c871..dd3d7680b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -29,6 +29,7 @@ module org.cryptomator.desktop { requires logback.classic; requires logback.core; + exports org.cryptomator.ui.traymenu to org.cryptomator.integrations.api; provides TrayMenuController with AwtTrayMenuController; opens org.cryptomator.common.settings to com.google.gson; diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 55f76d321..f3109e7bf 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -44,7 +44,7 @@ public class FxApplication { // init system tray final boolean hasTrayIcon; - if (SystemTray.isSupported() && settings.showTrayIcon().get()) { + if (settings.showTrayIcon().get() && trayMenu.get().isSupported()) { trayMenu.get().initializeTrayIcon(); Platform.setImplicitExit(false); // don't quit when closing all windows hasTrayIcon = true; diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index 034847913..6f791321f 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -1,11 +1,13 @@ package org.cryptomator.ui.traymenu; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.integrations.common.CheckAvailability; import org.cryptomator.integrations.common.Priority; import org.cryptomator.integrations.tray.ActionItem; import org.cryptomator.integrations.tray.SeparatorItem; import org.cryptomator.integrations.tray.SubMenuItem; import org.cryptomator.integrations.tray.TrayMenuController; +import org.cryptomator.integrations.tray.TrayMenuException; import org.cryptomator.integrations.tray.TrayMenuItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,18 +23,23 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; +@CheckAvailability @Priority(Priority.FALLBACK) public class AwtTrayMenuController implements TrayMenuController { private static final Logger LOG = LoggerFactory.getLogger(AwtTrayMenuController.class); - private TrayIcon trayIcon; - private PopupMenu menu = new PopupMenu(); + private final PopupMenu menu = new PopupMenu(); + + @CheckAvailability + public static boolean isAvailable() { + return SystemTray.isSupported(); + } @Override - public void showTrayIcon(InputStream rawImageData, Runnable defaultAction, String tooltip) throws IOException { - var image = Toolkit.getDefaultToolkit().createImage(rawImageData.readAllBytes()); - trayIcon = new TrayIcon(image, tooltip, menu); + public void showTrayIcon(byte[] rawImageData, Runnable defaultAction, String tooltip) { + var image = Toolkit.getDefaultToolkit().createImage(rawImageData); + var trayIcon = new TrayIcon(image, tooltip, menu); trayIcon.setImageAutoSize(true); if (SystemUtils.IS_OS_WINDOWS) { @@ -59,7 +66,7 @@ public class AwtTrayMenuController implements TrayMenuController { if (item instanceof ActionItem a) { var menuItem = new MenuItem(a.title()); menuItem.addActionListener(evt -> a.action().run()); - // TODO menuItem.setEnabled(a.enabled()); + menuItem.setEnabled(a.enabled()); menu.add(menuItem); } else if (item instanceof SeparatorItem) { menu.addSeparator(); diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java index b8e5d8c2b..ea8599b51 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuBuilder.java @@ -7,11 +7,14 @@ import org.cryptomator.integrations.tray.ActionItem; import org.cryptomator.integrations.tray.SeparatorItem; import org.cryptomator.integrations.tray.SubMenuItem; import org.cryptomator.integrations.tray.TrayMenuController; +import org.cryptomator.integrations.tray.TrayMenuException; import org.cryptomator.integrations.tray.TrayMenuItem; import org.cryptomator.ui.common.VaultService; import org.cryptomator.ui.fxapp.FxApplicationTerminator; import org.cryptomator.ui.fxapp.FxApplicationWindows; import org.cryptomator.ui.preferences.SelectedPreferencesTab; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Platform; @@ -27,6 +30,7 @@ import java.util.ResourceBundle; @TrayMenuScoped public class TrayMenuBuilder { + private static final Logger LOG = LoggerFactory.getLogger(TrayMenuBuilder.class); private static final String TRAY_ICON_MAC = "/img/tray_icon_mac.png"; private static final String TRAY_ICON = "/img/tray_icon.png"; @@ -56,15 +60,16 @@ public class TrayMenuBuilder { vaults.forEach(v -> { v.displayNameProperty().addListener(this::vaultListChanged); }); - rebuildMenu(); try (var image = getClass().getResourceAsStream(SystemUtils.IS_OS_MAC_OSX ? TRAY_ICON_MAC : TRAY_ICON)) { - trayMenu.showTrayIcon(image, this::showMainWindow, "Cryptomator"); + trayMenu.showTrayIcon(image.readAllBytes(), this::showMainWindow, "Cryptomator"); + rebuildMenu(); + initialized = true; } catch (IOException e) { throw new UncheckedIOException("Failed to load embedded resource", e); + } catch (TrayMenuException e) { + LOG.error("Adding tray icon failed", e); } - - initialized = true; } public boolean isInitialized() { @@ -88,11 +93,14 @@ public class TrayMenuBuilder { menu.add(new SubMenuItem(label, submenu)); } menu.add(new SeparatorItem()); - menu.add(new ActionItem(resourceBundle.getString("traymenu.lockAllVaults"), this::lockAllVaults)); + menu.add(new ActionItem(resourceBundle.getString("traymenu.lockAllVaults"), this::lockAllVaults, vaults.stream().anyMatch(Vault::isUnlocked))); menu.add(new ActionItem(resourceBundle.getString("traymenu.quitApplication"), this::quitApplication)); -// lockAllItem.setEnabled(!vaults.filtered(Vault::isUnlocked).isEmpty()); - trayMenu.updateTrayMenu(menu); + try { + trayMenu.updateTrayMenu(menu); + } catch (TrayMenuException e) { + LOG.error("Updating tray menu failed", e); + } } private List buildSubmenu(Vault vault) { diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java index 61861e12c..ba84171b3 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java @@ -24,8 +24,7 @@ public interface TrayMenuComponent { * @return true if a tray icon can be installed */ default boolean isSupported() { - // TODO add isSupported to API and move SystemTray.isSupported() to impl - return trayMenuController().isPresent() && SystemTray.isSupported(); + return trayMenuController().isPresent(); } /** @@ -38,11 +37,13 @@ public interface TrayMenuComponent { /** * Installs a tray icon to the system tray. * - * @throws IllegalStateException If already added + * @throws IllegalStateException If not {@link #isSupported() supported} */ default void initializeTrayIcon() throws IllegalStateException { Preconditions.checkState(isSupported(), "system tray not supported"); - trayMenuBuilder().initTrayMenu(); + if (!trayMenuBuilder().isInitialized()) { + trayMenuBuilder().initTrayMenu(); + } } @Subcomponent.Builder From ec909ce723f4e9f895b49e506a15d7b94c8d9727 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 4 Apr 2022 15:10:24 +0200 Subject: [PATCH 4/9] rethrow AWTException as TrayMenuException --- .../org/cryptomator/ui/traymenu/AwtTrayMenuController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index 6f791321f..b3a4b3f6e 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -37,7 +37,7 @@ public class AwtTrayMenuController implements TrayMenuController { } @Override - public void showTrayIcon(byte[] rawImageData, Runnable defaultAction, String tooltip) { + public void showTrayIcon(byte[] rawImageData, Runnable defaultAction, String tooltip) throws TrayMenuException { var image = Toolkit.getDefaultToolkit().createImage(rawImageData); var trayIcon = new TrayIcon(image, tooltip, menu); @@ -50,7 +50,7 @@ public class AwtTrayMenuController implements TrayMenuController { SystemTray.getSystemTray().add(trayIcon); LOG.debug("initialized tray icon"); } catch (AWTException e) { - LOG.error("Error adding tray icon", e); + throw new TrayMenuException("Failed to add icon to system tray.", e); } } From ceb3cbc43f9be9921343e8987f755c0ef6e946d4 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Mon, 4 Apr 2022 15:10:35 +0200 Subject: [PATCH 5/9] remove unused imports --- .../java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java index b3a4b3f6e..79f1dd628 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java +++ b/src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java @@ -19,8 +19,6 @@ import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; -import java.io.IOException; -import java.io.InputStream; import java.util.List; @CheckAvailability From c03bc9ed0b0d82c9b4e48565ee9510645e464303 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 5 Apr 2022 07:47:54 +0200 Subject: [PATCH 6/9] removed unused imports [ci skip] --- src/main/java/org/cryptomator/ui/fxapp/FxApplication.java | 3 --- .../java/org/cryptomator/ui/traymenu/TrayMenuComponent.java | 1 - 2 files changed, 4 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index f3109e7bf..b810a817f 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -8,9 +8,6 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Platform; -import javafx.stage.Stage; -import javafx.stage.StageStyle; -import java.awt.SystemTray; @FxApplicationScoped public class FxApplication { diff --git a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java index ba84171b3..02bf2aabd 100644 --- a/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java +++ b/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java @@ -9,7 +9,6 @@ import com.google.common.base.Preconditions; import dagger.Subcomponent; import org.cryptomator.integrations.tray.TrayMenuController; -import java.awt.SystemTray; import java.util.Optional; @TrayMenuScoped From 4c363a9abc5d2374af03caef5c56380ef3504d14 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 5 Apr 2022 08:14:14 +0200 Subject: [PATCH 7/9] dealing with deprecation --- .../cryptomator/common/PluginClassLoader.java | 67 ------------------- .../common/keychain/KeychainManagerTest.java | 9 +-- .../common/keychain/MapKeychainAccess.java | 15 ++++- 3 files changed, 19 insertions(+), 72 deletions(-) delete mode 100644 src/main/java/org/cryptomator/common/PluginClassLoader.java diff --git a/src/main/java/org/cryptomator/common/PluginClassLoader.java b/src/main/java/org/cryptomator/common/PluginClassLoader.java deleted file mode 100644 index 28c73cd2c..000000000 --- a/src/main/java/org/cryptomator/common/PluginClassLoader.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.cryptomator.common; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.file.FileVisitOption; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; - -@Deprecated // to be moved to integrations-api 1.1.0 -@Singleton -public class PluginClassLoader extends URLClassLoader { - - private static final Logger LOG = LoggerFactory.getLogger(PluginClassLoader.class); - private static final String NAME = "PluginClassLoader"; - private static final String JAR_SUFFIX = ".jar"; - - @Inject - public PluginClassLoader(Environment env) { - super(NAME, env.getPluginDir().map(PluginClassLoader::findJars).orElse(new URL[0]), PluginClassLoader.class.getClassLoader()); - } - - private static URL[] findJars(Path path) { - if (!Files.isDirectory(path)) { - return new URL[0]; - } else { - try { - var visitor = new JarVisitor(); - Files.walkFileTree(path, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, visitor); - return visitor.urls.toArray(URL[]::new); - } catch (IOException e) { - LOG.warn("Failed to scan plugin dir " + path, e); - return new URL[0]; - } - } - } - - private static final class JarVisitor extends SimpleFileVisitor { - - private final List urls = new ArrayList<>(); - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - if (attrs.isRegularFile() && file.getFileName().toString().toLowerCase().endsWith(JAR_SUFFIX)) { - try { - urls.add(file.toUri().toURL()); - } catch (MalformedURLException e) { - LOG.warn("Failed to create URL for jar file {}", file); - } - } - return FileVisitResult.CONTINUE; - } - } - -} diff --git a/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java b/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java index aa8b6e1f3..8c05609ce 100644 --- a/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java +++ b/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test; import javafx.application.Platform; import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.SimpleObjectProperty; +import java.time.Duration; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -23,7 +24,7 @@ public class KeychainManagerTest { @Test public void testStoreAndLoad() throws KeychainAccessException { KeychainManager keychainManager = new KeychainManager(new SimpleObjectProperty<>(new MapKeychainAccess())); - keychainManager.storePassphrase("test", "asd"); + keychainManager.storePassphrase("test", "Test", "asd"); Assertions.assertArrayEquals("asd".toCharArray(), keychainManager.loadPassphrase("test")); } @@ -42,7 +43,7 @@ public class KeychainManagerTest { public void testPropertyChangesWhenStoringPassword() throws KeychainAccessException, InterruptedException { KeychainManager keychainManager = new KeychainManager(new SimpleObjectProperty<>(new MapKeychainAccess())); ReadOnlyBooleanProperty property = keychainManager.getPassphraseStoredProperty("test"); - Assertions.assertEquals(false, property.get()); + Assertions.assertFalse(property.get()); keychainManager.storePassphrase("test", "bar"); @@ -52,8 +53,8 @@ public class KeychainManagerTest { result.set(property.get()); latch.countDown(); }); - latch.await(1, TimeUnit.SECONDS); - Assertions.assertEquals(true, result.get()); + Assertions.assertTimeoutPreemptively(Duration.ofSeconds(1), () -> latch.await()); + Assertions.assertTrue(result.get()); } } diff --git a/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java b/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java index dbffae92e..af5b4a9cc 100644 --- a/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java +++ b/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java @@ -5,6 +5,7 @@ *******************************************************************************/ package org.cryptomator.common.keychain; +import org.cryptomator.integrations.keychain.KeychainAccessException; import org.cryptomator.integrations.keychain.KeychainAccessProvider; import java.util.HashMap; @@ -20,7 +21,13 @@ class MapKeychainAccess implements KeychainAccessProvider { } @Override + @Deprecated public void storePassphrase(String key, CharSequence passphrase) { + throw new NoSuchMethodError("not implemented"); + } + + @Override + public void storePassphrase(String key, String displayName,CharSequence passphrase) { char[] pw = new char[passphrase.length()]; for (int i = 0; i < passphrase.length(); i++) { pw[i] = passphrase.charAt(i); @@ -39,7 +46,13 @@ class MapKeychainAccess implements KeychainAccessProvider { } @Override - public void changePassphrase(String key, CharSequence passphrase) { + @Deprecated + public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException { + throw new NoSuchMethodError("not implemented"); + } + + @Override + public void changePassphrase(String key, String displayName, CharSequence passphrase) { map.get(key); storePassphrase(key, passphrase); } From 9ece1f66a13efacfb26cfab0a18bee8c52c5dace Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 13 Apr 2022 07:16:19 +0200 Subject: [PATCH 8/9] bumped API to 1.1.0-rc1 --- pom.xml | 8 ++++---- .../common/keychain/KeychainManager.java | 12 ------------ .../common/keychain/KeychainManagerTest.java | 4 +--- .../common/keychain/MapKeychainAccess.java | 15 +-------------- 4 files changed, 6 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index 98994551d..c216885d7 100644 --- a/pom.xml +++ b/pom.xml @@ -28,10 +28,10 @@ 2.4.0 - 1.1.0-beta3 - 1.1.0-beta1 - 1.1.0-beta1 - 1.1.0-beta1 + 1.1.0-rc1 + 1.1.0-beta2 + 1.1.0-beta2 + 1.1.0-beta2 1.3.3 1.3.3 1.2.7 diff --git a/src/main/java/org/cryptomator/common/keychain/KeychainManager.java b/src/main/java/org/cryptomator/common/keychain/KeychainManager.java index e0269348a..48b0a0ed5 100644 --- a/src/main/java/org/cryptomator/common/keychain/KeychainManager.java +++ b/src/main/java/org/cryptomator/common/keychain/KeychainManager.java @@ -43,12 +43,6 @@ public class KeychainManager implements KeychainAccessProvider { return getClass().getName(); } - @Override - @Deprecated - public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException { - storePassphrase(key, null, passphrase); - } - @Override public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException { getKeychainOrFail().storePassphrase(key, displayName, passphrase); @@ -68,12 +62,6 @@ public class KeychainManager implements KeychainAccessProvider { setPassphraseStored(key, false); } - @Override - @Deprecated - public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException { - changePassphrase(key, null, passphrase); - } - @Override public void changePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException { if (isPassphraseStored(key)) { diff --git a/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java b/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java index 8c05609ce..abf803e1e 100644 --- a/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java +++ b/src/test/java/org/cryptomator/common/keychain/KeychainManagerTest.java @@ -2,11 +2,9 @@ package org.cryptomator.common.keychain; import org.cryptomator.integrations.keychain.KeychainAccessException; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -45,7 +43,7 @@ public class KeychainManagerTest { ReadOnlyBooleanProperty property = keychainManager.getPassphraseStoredProperty("test"); Assertions.assertFalse(property.get()); - keychainManager.storePassphrase("test", "bar"); + keychainManager.storePassphrase("test", null,"bar"); AtomicBoolean result = new AtomicBoolean(false); CountDownLatch latch = new CountDownLatch(1); diff --git a/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java b/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java index af5b4a9cc..c4baa96fa 100644 --- a/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java +++ b/src/test/java/org/cryptomator/common/keychain/MapKeychainAccess.java @@ -5,7 +5,6 @@ *******************************************************************************/ package org.cryptomator.common.keychain; -import org.cryptomator.integrations.keychain.KeychainAccessException; import org.cryptomator.integrations.keychain.KeychainAccessProvider; import java.util.HashMap; @@ -20,12 +19,6 @@ class MapKeychainAccess implements KeychainAccessProvider { return getClass().getName(); } - @Override - @Deprecated - public void storePassphrase(String key, CharSequence passphrase) { - throw new NoSuchMethodError("not implemented"); - } - @Override public void storePassphrase(String key, String displayName,CharSequence passphrase) { char[] pw = new char[passphrase.length()]; @@ -45,16 +38,10 @@ class MapKeychainAccess implements KeychainAccessProvider { map.remove(key); } - @Override - @Deprecated - public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException { - throw new NoSuchMethodError("not implemented"); - } - @Override public void changePassphrase(String key, String displayName, CharSequence passphrase) { map.get(key); - storePassphrase(key, passphrase); + storePassphrase(key, displayName, passphrase); } @Override From c3969f2f33cd8de41be7aa9d08712ee651f7cf97 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 27 Apr 2022 15:19:54 +0200 Subject: [PATCH 9/9] bumped integrations version --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d9feb3fe5..9bdb55185 100644 --- a/pom.xml +++ b/pom.xml @@ -28,10 +28,10 @@ 2.4.0 - 1.1.0-rc1 - 1.1.0-beta2 - 1.1.0-beta2 - 1.1.0-beta2 + 1.1.0 + 1.1.0 + 1.1.0 + 1.1.0 1.3.3 1.3.3 1.2.7