From 68b79cc9103f0cb1a9ba1e5b634614c517f5a023 Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Thu, 8 Apr 2021 22:27:41 +0200 Subject: [PATCH] [bluetooth] Graciously handle systems without DBus (#10153) Signed-off-by: John Marshall --- .../bluez/internal/DeviceManagerFactory.java | 29 +++++++++++---- .../bluez/internal/DeviceManagerWrapper.java | 36 ++++++++++++------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerFactory.java b/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerFactory.java index 75a8b73cbc176..0abeade1f80ff 100644 --- a/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerFactory.java +++ b/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerFactory.java @@ -51,7 +51,7 @@ public class DeviceManagerFactory { private final BlueZPropertiesChangedHandler changeHandler = new BlueZPropertiesChangedHandler(); - private @Nullable CompletableFuture deviceManagerFuture; + private @Nullable CompletableFuture<@Nullable DeviceManager> deviceManagerFuture; private @Nullable CompletableFuture deviceManagerWrapperFuture; public BlueZPropertiesChangedHandler getPropertiesChangedHandler() { @@ -79,7 +79,13 @@ public void initialize() { // Experimental - seems reuse does not work } catch (IllegalStateException e) { // Exception caused by first call to the library - return DeviceManager.createInstance(false); + try { + return DeviceManager.createInstance(false); + } catch (DBusException ex) { + // we might be on a system without DBus, such as macOS or Windows + logger.debug("Failed to initialize DeviceManager: {}", ex.getMessage()); + return null; + } } }, scheduler); @@ -90,8 +96,10 @@ public void initialize() { int count = tryCount.incrementAndGet(); try { logger.debug("Registering property handler attempt: {}", count); - devManager.registerPropertyHandler(changeHandler); - logger.debug("Successfully registered property handler"); + if (devManager != null) { + devManager.registerPropertyHandler(changeHandler); + logger.debug("Successfully registered property handler"); + } return new DeviceManagerWrapper(devManager); } catch (DBusException e) { if (count < 3) { @@ -103,7 +111,12 @@ public void initialize() { }, scheduler); }).whenComplete((devManagerWrapper, th) -> { if (th != null) { - logger.warn("Failed to initialize DeviceManager: {}", th.getMessage()); + if (th.getCause() instanceof DBusException) { + // we might be on a system without DBus, such as macOS or Windows + logger.debug("Failed to initialize DeviceManager: {}", th.getMessage()); + } else { + logger.warn("Failed to initialize DeviceManager: {}", th.getMessage()); + } } }); } @@ -114,7 +127,11 @@ public void dispose() { if (stage1 != null) { if (!stage1.cancel(true)) { // a failure to cancel means that the stage completed normally - stage1.thenAccept(DeviceManager::closeConnection); + stage1.thenAccept(devManager -> { + if (devManager != null) { + devManager.closeConnection(); + } + }); } } this.deviceManagerFuture = null; diff --git a/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerWrapper.java b/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerWrapper.java index 93453d99d8348..cbfeeae06207b 100644 --- a/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerWrapper.java +++ b/bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerWrapper.java @@ -14,6 +14,7 @@ import java.util.Collection; import java.util.List; +import java.util.Set; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -32,25 +33,32 @@ @NonNullByDefault public class DeviceManagerWrapper { - private DeviceManager deviceManager; + private @Nullable DeviceManager deviceManager; - public DeviceManagerWrapper(DeviceManager deviceManager) { + public DeviceManagerWrapper(@Nullable DeviceManager deviceManager) { this.deviceManager = deviceManager; } public synchronized Collection scanForBluetoothAdapters() { - return deviceManager.scanForBluetoothAdapters(); + if (deviceManager != null) { + return deviceManager.scanForBluetoothAdapters(); + } else { + return Set.of(); + } } public synchronized @Nullable BluetoothAdapter getAdapter(BluetoothAddress address) { - // we don't use `deviceManager.getAdapter` here since it might perform a scan if the adapter is missing. - String addr = address.toString(); - List adapters = deviceManager.getAdapters(); - if (adapters != null) { - for (BluetoothAdapter btAdapter : adapters) { - String btAddr = btAdapter.getAddress(); - if (addr.equalsIgnoreCase(btAddr)) { - return btAdapter; + DeviceManager devMgr = deviceManager; + if (devMgr != null) { + // we don't use `deviceManager.getAdapter` here since it might perform a scan if the adapter is missing. + String addr = address.toString(); + List adapters = devMgr.getAdapters(); + if (adapters != null) { + for (BluetoothAdapter btAdapter : adapters) { + String btAddr = btAdapter.getAddress(); + if (addr.equalsIgnoreCase(btAddr)) { + return btAdapter; + } } } } @@ -58,6 +66,10 @@ public synchronized Collection scanForBluetoothAdapters() { } public synchronized List getDevices(BluetoothAdapter adapter) { - return deviceManager.getDevices(adapter.getAddress(), true); + if (deviceManager != null) { + return deviceManager.getDevices(adapter.getAddress(), true); + } else { + return List.of(); + } } }