From 74586a9df1d0e82031453d7b5c20f448e7f8f4ef Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 20 Dec 2024 15:55:54 +0800 Subject: [PATCH] Bluetooth (Linux): improve performance 1. ignore unpaired devices 2. ignore disconnected devices when `showDisconnected == false` --- src/detection/bluetooth/bluetooth_linux.c | 82 +++++++++++++++-------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/src/detection/bluetooth/bluetooth_linux.c b/src/detection/bluetooth/bluetooth_linux.c index ea1f09719..beaaba9b1 100644 --- a/src/detection/bluetooth/bluetooth_linux.c +++ b/src/detection/bluetooth/bluetooth_linux.c @@ -45,16 +45,16 @@ array [ //root ] */ -static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device) +static bool detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device) { if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) - return; + return true; DBusMessageIter dictIter; dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter); if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING) - return; + return true; const char* deviceProperty; dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty); @@ -75,6 +75,13 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue } else if(ffStrEquals(deviceProperty, "Connected")) ffDBusGetBool(dbus, &dictIter, &device->connected); + else if(ffStrEquals(deviceProperty, "Paired")) + { + bool paired = true; + ffDBusGetBool(dbus, &dictIter, &paired); + if (!paired) return false; + } + return true; } static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device) @@ -104,32 +111,37 @@ static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFB do { - detectBluetoothValue(dbus, &arrayIter, device); + bool shouldContinue = detectBluetoothValue(dbus, &arrayIter, device); + if (!shouldContinue) + { + ffStrbufClear(&device->name); + break; + } } while (dbus->lib->ffdbus_message_iter_next(&arrayIter)); } -static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter) +static FFBluetoothResult* detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter) { if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) - return; + return NULL; DBusMessageIter dictIter; dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter); if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH) - return; + return NULL; const char* objectPath; dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath); // We don't want adapter objects if(!ffStrContains(objectPath, "/dev_")) - return; + return NULL; dbus->lib->ffdbus_message_iter_next(&dictIter); if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY) - return; + return NULL; DBusMessageIter arrayIter; dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter); @@ -146,16 +158,10 @@ static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessage detectBluetoothProperty(dbus, &arrayIter, device); } while (dbus->lib->ffdbus_message_iter_next(&arrayIter)); - if(device->name.length == 0) - { - ffStrbufDestroy(&device->name); - ffStrbufDestroy(&device->address); - ffStrbufDestroy(&device->type); - --devices->length; - } + return device; } -static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter) +static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter, int32_t connectedCount) { if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) return; @@ -165,11 +171,25 @@ static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIt do { - detectBluetoothObject(devices, dbus, &arrayIter); + FFBluetoothResult* device = detectBluetoothObject(devices, dbus, &arrayIter); + + if (device) + { + if(device->name.length == 0 || (connectedCount > 0 && !device->connected)) + { + ffStrbufDestroy(&device->name); + ffStrbufDestroy(&device->address); + ffStrbufDestroy(&device->type); + --devices->length; + } + + if (device->connected && --connectedCount == 0) + break; + } } while (dbus->lib->ffdbus_message_iter_next(&arrayIter)); } -static const char* detectBluetooth(FFlist* devices) +static const char* detectBluetooth(FFlist* devices, int32_t connectedCount) { FFDBusData dbus; const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus); @@ -187,26 +207,27 @@ static const char* detectBluetooth(FFlist* devices) return "Failed to get root iterator of GetManagedObjects"; } - detectBluetoothRoot(devices, &dbus, &rootIter); + detectBluetoothRoot(devices, &dbus, &rootIter, connectedCount); dbus.lib->ffdbus_message_unref(managedObjects); return NULL; } -static bool hasConnectedDevices(void) +static uint32_t connectedDevices(void) { FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth"); if(dirp == NULL) - return false; + return 0; + uint32_t result = 0; struct dirent* entry; while ((entry = readdir(dirp)) != NULL) { - if (strchr(entry->d_name, ':') != NULL) // ignore connected devices - return true; + if (strchr(entry->d_name, ':') != NULL) + ++result; } - return false; + return result; } #endif @@ -214,10 +235,15 @@ static bool hasConnectedDevices(void) const char* ffDetectBluetooth(FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */) { #ifdef FF_HAVE_DBUS - if (!options->showDisconnected && !hasConnectedDevices()) - return NULL; + int32_t connectedCount = -1; + if (!options->showDisconnected) + { + connectedCount = (int32_t) connectedDevices(); + if (connectedCount == 0) + return NULL; + } - return detectBluetooth(devices); + return detectBluetooth(devices, connectedCount); #else return "Fastfetch was compiled without DBus support"; #endif