Skip to content

Commit

Permalink
Merge branch 'develop' into release/1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
infeo committed Feb 9, 2023
2 parents cc65fd9 + 447782d commit e2c7ff0
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.cryptomator.linux.revealpath;

import com.google.common.base.Preconditions;
import org.cryptomator.integrations.revealpath.RevealFailedException;
import org.cryptomator.integrations.revealpath.RevealPathService;

Expand All @@ -15,8 +16,12 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class DBusFileMangerRevealPath implements RevealPathService {
/**
* RevealPathService provider using the <a href="https://freedesktop.org/wiki/Specifications/file-manager-interface/">DBus freedesktop FileManager1 interface</a> and dbus-send command.
*/
public class DBusSendRevealPathService implements RevealPathService {

private static final String FILEMANAGER1_XML_ELEMENT = "<interface name=\"org.freedesktop.FileManager1\">";
private static final String FOR_FOLDERS = "org.freedesktop.FileManager1.ShowFolders";
private static final String FOR_FILES = "org.freedesktop.FileManager1.ShowItems";
private static final int TIMEOUT_THRESHOLD = 5000;
Expand Down Expand Up @@ -56,24 +61,52 @@ public void reveal(Path path) throws RevealFailedException {

@Override
public boolean isSupported() {
CountDownLatch waitBarrier = new CountDownLatch(3);
ProcessBuilder builderExistsDbusSend = new ProcessBuilder().command("which", "dbus-send");
ProcessBuilder builderExistsNautilus = new ProcessBuilder().command("which", "nautilus");
ProcessBuilder builderExistsDolphin = new ProcessBuilder().command("which", "dolphin");
CountDownLatch waitBarrier = new CountDownLatch(2);
ProcessBuilder dbusSendExistsBuilder = new ProcessBuilder().command("test", " `command -v dbus-send`");
ProcessBuilder fileManager1ExistsBuilder = createFileManager1Check();

try {
var existsDbusSend = builderExistsDbusSend.start();
existsDbusSend.onExit().thenRun(waitBarrier::countDown);
var existsNautilus = builderExistsNautilus.start();
existsNautilus.onExit().thenRun(waitBarrier::countDown);
var existsDolphin = builderExistsDolphin.start();
existsDolphin.onExit().thenRun(waitBarrier::countDown);
var dbusSendExists = dbusSendExistsBuilder.start();
dbusSendExists.onExit().thenRun(waitBarrier::countDown);
var fileManager1Exists = fileManager1ExistsBuilder.start();
fileManager1Exists.onExit().thenRun(waitBarrier::countDown);

if (waitBarrier.await(TIMEOUT_THRESHOLD, TimeUnit.MILLISECONDS)) {
return existsDbusSend.exitValue() == 0 && (existsNautilus.exitValue() == 0 | existsDolphin.exitValue() == 0);
if (dbusSendExists.exitValue() == 0 && fileManager1Exists.exitValue() == 0) {
return parseOutputForFileManagerInterface(fileManager1Exists);
}
}
} catch (IOException | InterruptedException e) {
//NO-OP
}
return false;
}

/**
* Parses process stdout to see if the answer contains "{@value FILEMANAGER1_XML_ELEMENT}".
* DBus introspection output is defined in the <a href="https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">dbus spec</a>.
*
* @param fileManager1Process The already exited process for checking the FileManager1 interface
* @return {@code true} if the interface is found in the introspection output, otherwise false
* @throws IOException if the Inputer reader on the process output cannot be created
*/
private boolean parseOutputForFileManagerInterface(Process fileManager1Process) throws IOException {
Preconditions.checkState(!fileManager1Process.isAlive());
try (var reader = fileManager1Process.inputReader(StandardCharsets.UTF_8)) {
return reader.lines().map(String::trim).anyMatch(FILEMANAGER1_XML_ELEMENT::equals);
}
}

private static ProcessBuilder createFileManager1Check() {
return new ProcessBuilder().command(
"dbus-send",
"--session",
"--print-reply",
"--reply-timeout=" + TIMEOUT_THRESHOLD,
"--dest=org.freedesktop.FileManager1",
"--type=method_call",
"/org/freedesktop/FileManager1",
"org.freedesktop.DBus.Introspectable.Introspect"
);
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
org.cryptomator.linux.revealpath.DBusFileMangerRevealPath
org.cryptomator.linux.revealpath.DBusSendRevealPathService
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.cryptomator.linux.keychain;
package org.cryptomator.linux.revealpath;

import org.cryptomator.integrations.revealpath.RevealFailedException;
import org.cryptomator.linux.revealpath.DBusFileMangerRevealPath;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Disabled;
Expand All @@ -14,10 +13,10 @@

@EnabledOnOs(OS.LINUX)
@Disabled
public class DbusFileManagerRevealPathTest {
public class DBusSendRevealPathServiceTest {

@TempDir Path tmpDir;
DBusFileMangerRevealPath inTest = new DBusFileMangerRevealPath();
DBusSendRevealPathService inTest = new DBusSendRevealPathService();

@Test
public void testIsSupported() {
Expand All @@ -26,15 +25,15 @@ public void testIsSupported() {

@Test
public void testRevealSuccess() {
DBusFileMangerRevealPath revealPathService = new DBusFileMangerRevealPath();
DBusSendRevealPathService revealPathService = new DBusSendRevealPathService();
Assumptions.assumeTrue(revealPathService.isSupported());

Assertions.assertDoesNotThrow(() -> revealPathService.reveal(tmpDir));
}

@Test
public void testRevealFail() {
DBusFileMangerRevealPath revealPathService = new DBusFileMangerRevealPath();
DBusSendRevealPathService revealPathService = new DBusSendRevealPathService();
Assumptions.assumeTrue(revealPathService.isSupported());

Assertions.assertThrows(RevealFailedException.class, () -> revealPathService.reveal(tmpDir.resolve("foobar")));
Expand Down

0 comments on commit e2c7ff0

Please sign in to comment.