Skip to content

Commit 6c33f55

Browse files
committed
only check for FileManager1 interface
1 parent 1344975 commit 6c33f55

File tree

1 file changed

+24
-50
lines changed

1 file changed

+24
-50
lines changed

src/main/java/org/cryptomator/linux/revealpath/DBusSendRevealPathService.java

Lines changed: 24 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.cryptomator.linux.revealpath;
22

3+
import com.google.common.base.Preconditions;
34
import org.cryptomator.integrations.revealpath.RevealFailedException;
45
import org.cryptomator.integrations.revealpath.RevealPathService;
56

@@ -11,15 +12,16 @@
1112
import java.nio.file.Path;
1213
import java.nio.file.attribute.BasicFileAttributes;
1314
import java.util.Arrays;
14-
import java.util.List;
15-
import java.util.Objects;
1615
import java.util.concurrent.CountDownLatch;
1716
import java.util.concurrent.TimeUnit;
1817
import java.util.stream.Collectors;
1918

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

22-
private static final String[] FILEMANAGER_OBJECT_PATHS = {"/org/gnome/Nautilus", "/org/kde/dolphin", "/org/xfce/Thunar"};
24+
private static final String FILEMANAGER1_XML_ELEMENT = "<interface name=\"org.freedesktop.FileManager1\">";
2325
private static final String FOR_FOLDERS = "org.freedesktop.FileManager1.ShowFolders";
2426
private static final String FOR_FILES = "org.freedesktop.FileManager1.ShowItems";
2527
private static final int TIMEOUT_THRESHOLD = 5000;
@@ -59,29 +61,19 @@ public void reveal(Path path) throws RevealFailedException {
5961

6062
@Override
6163
public boolean isSupported() {
62-
CountDownLatch waitBarrier = new CountDownLatch(FILEMANAGER_OBJECT_PATHS.length + 1);
63-
ProcessBuilder dbusSendExistBuilder = new ProcessBuilder().command("test", " `command -v dbus-send`");
64-
List<ProcessBuilder> fileManagerExistBuilders = Arrays.stream(FILEMANAGER_OBJECT_PATHS)
65-
.map(DBusSendRevealPathService::createDbusObjectCheck).toList();
64+
CountDownLatch waitBarrier = new CountDownLatch(2);
65+
ProcessBuilder dbusSendExistsBuilder = new ProcessBuilder().command("test", " `command -v dbus-send`");
66+
ProcessBuilder fileManager1ExistsBuilder = createFileManager1Check();
6667

6768
try {
68-
var existsDbusSend = dbusSendExistBuilder.start();
69-
existsDbusSend.onExit().thenRun(waitBarrier::countDown);
70-
//TODO: process process-output in paralell
71-
List<Process> fileManagerChecks = fileManagerExistBuilders.stream().map(builder -> {
72-
try {
73-
return builder.start();
74-
} catch (IOException e) {
75-
waitBarrier.countDown(); //to prevent blocking
76-
return null;
77-
}
78-
}).filter(Objects::nonNull).toList();
69+
var dbusSendExists = dbusSendExistsBuilder.start();
70+
dbusSendExists.onExit().thenRun(waitBarrier::countDown);
71+
var fileManager1Exists = fileManager1ExistsBuilder.start();
72+
fileManager1Exists.onExit().thenRun(waitBarrier::countDown);
7973

80-
fileManagerChecks.forEach(process -> process.onExit().thenRun(waitBarrier::countDown));
8174
if (waitBarrier.await(TIMEOUT_THRESHOLD, TimeUnit.MILLISECONDS)) {
82-
var zeroExitfileManagerChecks = fileManagerChecks.stream().filter(p -> p.exitValue() == 0).toList();
83-
if (existsDbusSend.exitValue() == 0 && zeroExitfileManagerChecks.size() != 0) {
84-
return parseOutputsForActualDBusObject(zeroExitfileManagerChecks);
75+
if (dbusSendExists.exitValue() == 0 && fileManager1Exists.exitValue() == 0) {
76+
return parseOutputForFileManagerInterface(fileManager1Exists);
8577
}
8678
}
8779
} catch (IOException | InterruptedException e) {
@@ -91,47 +83,29 @@ public boolean isSupported() {
9183
}
9284

9385
/**
94-
* Parses process stdout to see if dbus-send answer is just an empty node.
95-
* <p>
96-
* Some dbus-send implementations return on calling methods on not-existing objects an empty node
97-
* <pre>
98-
* &lt;node&gt;
99-
* &lt;/node&gt;
100-
* </pre>
101-
* instead of throwing an error.
102-
* <p>
103-
* Regarding parsing, see the dbus spec <a href="https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">on the introsepction format</a>.
86+
* Parses process stdout to see if the answer contains "{@value FILEMANAGER1_XML_ELEMENT}".
87+
* DBus introspection output is defined in the <a href="https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">dbus spec</a>.
10488
*
105-
* @param dbusChecks List of dbus-send processes with zero-exitcode
106-
* @return if one dbus-send output contains actual content
89+
* @param fileManager1Process The already exited process for checking the FileManager1 interface
90+
* @return {@code true} if the interface is found in the introspection output, otherwise false
10791
* @throws IOException if the Inputer reader on the process output cannot be created
10892
*/
109-
private boolean parseOutputsForActualDBusObject(List<Process> dbusChecks) throws IOException {
110-
for (var check : dbusChecks) {
111-
try (var reader = check.inputReader(StandardCharsets.UTF_8)) {
112-
boolean passedInitialNode = false;
113-
var line = reader.readLine();
114-
while (line != null) {
115-
if (passedInitialNode) {
116-
return !line.equals("</node>");
117-
}
118-
passedInitialNode = line.startsWith("<node"); //root node might also contain name, hence no closing bracket
119-
line = reader.readLine();
120-
}
121-
}
93+
private boolean parseOutputForFileManagerInterface(Process fileManager1Process) throws IOException {
94+
Preconditions.checkState(!fileManager1Process.isAlive());
95+
try (var reader = fileManager1Process.inputReader(StandardCharsets.UTF_8)) {
96+
return reader.lines().map(String::trim).anyMatch(FILEMANAGER1_XML_ELEMENT::equals);
12297
}
123-
return false;
12498
}
12599

126-
private static ProcessBuilder createDbusObjectCheck(String dbusObjectPath) {
100+
private static ProcessBuilder createFileManager1Check() {
127101
return new ProcessBuilder().command(
128102
"dbus-send",
129103
"--session",
130104
"--print-reply",
131105
"--reply-timeout=" + TIMEOUT_THRESHOLD,
132106
"--dest=org.freedesktop.FileManager1",
133107
"--type=method_call",
134-
dbusObjectPath,
108+
"/org/freedesktop/FileManager1",
135109
"org.freedesktop.DBus.Introspectable.Introspect"
136110
);
137111
}

0 commit comments

Comments
 (0)