]> git.basschouten.com Git - openhab-addons.git/commitdiff
[bluetooth] Graciously handle systems without DBus (#10153)
authorKai Kreuzer <kai@openhab.org>
Thu, 8 Apr 2021 20:27:41 +0000 (22:27 +0200)
committerGitHub <noreply@github.com>
Thu, 8 Apr 2021 20:27:41 +0000 (22:27 +0200)
bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerFactory.java
bundles/org.openhab.binding.bluetooth.bluez/src/main/java/org/openhab/binding/bluetooth/bluez/internal/DeviceManagerWrapper.java

index 75a8b73cbc176f76656bc1e86bf9b8494515c3ae..0abeade1f80ff65c73c439647811fa1f83a7d259 100644 (file)
@@ -51,7 +51,7 @@ public class DeviceManagerFactory {
 
     private final BlueZPropertiesChangedHandler changeHandler = new BlueZPropertiesChangedHandler();
 
-    private @Nullable CompletableFuture<DeviceManager> deviceManagerFuture;
+    private @Nullable CompletableFuture<@Nullable DeviceManager> deviceManagerFuture;
     private @Nullable CompletableFuture<DeviceManagerWrapper> deviceManagerWrapperFuture;
 
     public BlueZPropertiesChangedHandler getPropertiesChangedHandler() {
@@ -79,7 +79,13 @@ public class DeviceManagerFactory {
                 // 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 class DeviceManagerFactory {
                 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 class DeviceManagerFactory {
             }, 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 class DeviceManagerFactory {
         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;
index 93453d99d83486e4ac857755ee9ea15bc59316b8..cbfeeae06207b7c5c214aae14bd0458ab94beff9 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.bluetooth.bluez.internal;
 
 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 @@ import com.github.hypfvieh.bluetooth.wrapper.BluetoothDevice;
 @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<BluetoothAdapter> 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<BluetoothAdapter> 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<BluetoothAdapter> 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 class DeviceManagerWrapper {
     }
 
     public synchronized List<BluetoothDevice> getDevices(BluetoothAdapter adapter) {
-        return deviceManager.getDevices(adapter.getAddress(), true);
+        if (deviceManager != null) {
+            return deviceManager.getDevices(adapter.getAddress(), true);
+        } else {
+            return List.of();
+        }
     }
 }