package org.argeo.cms.dbus; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import org.argeo.api.cms.CmsEventBus; import org.argeo.api.cms.CmsLog; import org.freedesktop.dbus.bin.EmbeddedDBusDaemon; import org.freedesktop.dbus.connections.BusAddress; import org.freedesktop.dbus.connections.impl.DBusConnection; import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder; import org.freedesktop.dbus.exceptions.DBusException; public class CmsDBusImpl implements CmsDBus { private final static CmsLog log = CmsLog.getLog(CmsDBusImpl.class); private BusAddress sessionBusAddress; private EmbeddedDBusDaemon dBusDaemon; private CmsEventBus cmsEventBus; public void start() { try { final String envSessionBusAddress = System.getenv(DBUS_SESSION_BUS_ADDRESS); if (envSessionBusAddress != null) { sessionBusAddress = BusAddress.of(envSessionBusAddress); // !! We must first initialise a connection, otherwise there are classloader issues later on try (DBusConnection dBusConnection = DBusConnectionBuilder.forAddress(sessionBusAddress) .withShared(false).build()) { } log.debug(() -> "Found session DBus with address " + sessionBusAddress); } else { Path socketLocation = Paths.get(System.getProperty("user.home"), ".cache", "argeo", "bus"); Files.createDirectories(socketLocation.getParent()); // TODO escape : on Windows? String embeddedSessionBusAddress = "unix:path=" + socketLocation.toUri().getPath(); dBusDaemon = new EmbeddedDBusDaemon(embeddedSessionBusAddress); dBusDaemon.startInBackgroundAndWait(30 * 1000); sessionBusAddress = BusAddress.of(embeddedSessionBusAddress); try (DBusConnection dBusConnection = DBusConnectionBuilder.forAddress(sessionBusAddress) .withShared(false).build()) { } log.debug(() -> "Started embedded session DBus with address " + sessionBusAddress); // TODO set environment variable? } } catch (DBusException | IOException e) { throw new IllegalStateException("Cannot find a session bus", e); } } public void stop() { if (dBusDaemon != null) { try { dBusDaemon.close(); } catch (IOException e) { log.error("Cannot close embedded DBus daemon", e); } } } @Override public DBusConnection openSessionConnection() { try { DBusConnection dBusConnection = DBusConnectionBuilder.forAddress(sessionBusAddress).withShared(false) .build(); // TODO track all connections? return dBusConnection; } catch (DBusException e) { e.printStackTrace(); throw new IllegalStateException("Cannot open connection to session DBus", e); } } public void setCmsEventBus(CmsEventBus cmsEventBus) { this.cmsEventBus = cmsEventBus; } }