From 7e2bc3eeef5daaf746d20ffce100b4d24bc59dc7 Mon Sep 17 00:00:00 2001 From: Saiqi Jia Date: Fri, 12 May 2023 23:43:26 +0800 Subject: [PATCH] Support MAC address as the identifier for bluetooth devices --- .../src/View/DeviceSelectorView.swift | 4 +- .../SettingsWindow/src/View/DevicesView.swift | 58 ++++++++++++------- .../swift/LibKrbn/ConnectedDevices.swift | 1 + .../LibKrbn/Models/ConnectedDevice.swift | 4 ++ .../include/libkrbn/impl/libkrbn_cpp.hpp | 1 + src/lib/libkrbn/include/libkrbn/libkrbn.h | 2 + .../libkrbn/src/libkrbn_connected_devices.cpp | 10 ++++ src/share/device_properties.hpp | 16 +++++ src/share/manipulator/conditions/device.hpp | 10 ++++ src/share/types/device_identifiers.hpp | 19 ++++++ .../json/connected_devices.json | 10 +++- .../json/ill_formed_name_expected.json | 1 + .../src/connected_devices_test.hpp | 18 +++++- .../src/connected_devices/src/device_test.hpp | 9 +++ .../json/to_json_example.json | 3 + .../src/core_configuration_test.hpp | 12 ++++ .../core_configuration/src/device_test.hpp | 21 ++++++- .../src/manipulator_factory_test.hpp | 6 +- .../json/device_if.jsonc | 3 + .../src/device_exists_test.hpp | 8 +-- .../src/device_test.hpp | 38 ++++++------ .../share/manipulator_conditions_helper.hpp | 4 ++ .../src/types/src/device_identifiers_test.hpp | 5 ++ 23 files changed, 210 insertions(+), 53 deletions(-) diff --git a/src/apps/SettingsWindow/src/View/DeviceSelectorView.swift b/src/apps/SettingsWindow/src/View/DeviceSelectorView.swift index cd74628a2..8b9a2e565 100644 --- a/src/apps/SettingsWindow/src/View/DeviceSelectorView.swift +++ b/src/apps/SettingsWindow/src/View/DeviceSelectorView.swift @@ -25,12 +25,14 @@ struct DeviceSelectorView: View { Button(action: { selectedDevice = connectedDeviceSetting.connectedDevice }) { + let noId = connectedDeviceSetting.connectedDevice.vendorId == 0 && connectedDeviceSetting.connectedDevice.productId == 0 + let label = noId ? connectedDeviceSetting.connectedDevice.deviceAddress : "\(String(connectedDeviceSetting.connectedDevice.vendorId)),\(String(connectedDeviceSetting.connectedDevice.productId))" HStack { Text( """ \(connectedDeviceSetting.connectedDevice.productName) \ (\(connectedDeviceSetting.connectedDevice.manufacturerName)) \ - [\(String(connectedDeviceSetting.connectedDevice.vendorId)),\(String(connectedDeviceSetting.connectedDevice.productId))] + [\(label)] """ ) diff --git a/src/apps/SettingsWindow/src/View/DevicesView.swift b/src/apps/SettingsWindow/src/View/DevicesView.swift index 2e6301b04..44a3bfa3f 100644 --- a/src/apps/SettingsWindow/src/View/DevicesView.swift +++ b/src/apps/SettingsWindow/src/View/DevicesView.swift @@ -94,30 +94,44 @@ struct DevicesView: View { if connectedDeviceSetting.connectedDevice.transport != "FIFO" { VStack(alignment: .trailing, spacing: 4.0) { - HStack(alignment: .firstTextBaseline, spacing: 0) { - Spacer() - - Text("Vendor ID: ") - - Text( - String( - format: "%5d (0x%04x)", - connectedDeviceSetting.connectedDevice.vendorId, - connectedDeviceSetting.connectedDevice.vendorId) - ) + if connectedDeviceSetting.connectedDevice.vendorId != 0 { + HStack(alignment: .firstTextBaseline, spacing: 0) { + Spacer() + + Text("Vendor ID: ") + + Text( + String( + format: "%5d (0x%04x)", + connectedDeviceSetting.connectedDevice.vendorId, + connectedDeviceSetting.connectedDevice.vendorId) + ) + } } - HStack(alignment: .center, spacing: 0) { - Spacer() - - Text("Product ID: ") - - Text( - String( - format: "%5d (0x%04x)", - connectedDeviceSetting.connectedDevice.productId, - connectedDeviceSetting.connectedDevice.productId) - ) + if connectedDeviceSetting.connectedDevice.productId != 0 { + HStack(alignment: .center, spacing: 0) { + Spacer() + + Text("Product ID: ") + + Text( + String( + format: "%5d (0x%04x)", + connectedDeviceSetting.connectedDevice.productId, + connectedDeviceSetting.connectedDevice.productId) + ) + } + } + + if !connectedDeviceSetting.connectedDevice.deviceAddress.isEmpty { + HStack(alignment: .center, spacing: 0) { + Spacer() + + Text("Device Address: ") + + Text(connectedDeviceSetting.connectedDevice.deviceAddress) + } } } .font(.custom("Menlo", size: 12.0)) diff --git a/src/apps/share/swift/LibKrbn/ConnectedDevices.swift b/src/apps/share/swift/LibKrbn/ConnectedDevices.swift index 4a7cb9e6c..88cd97247 100644 --- a/src/apps/share/swift/LibKrbn/ConnectedDevices.swift +++ b/src/apps/share/swift/LibKrbn/ConnectedDevices.swift @@ -68,6 +68,7 @@ extension LibKrbn { transport: transport, vendorId: libkrbn_connected_devices_get_vendor_id(libkrbnConnectedDevices, i), productId: libkrbn_connected_devices_get_product_id(libkrbnConnectedDevices, i), + deviceAddress: libkrbn_connected_devices_get_device_address(libkrbnConnectedDevices, i), isKeyboard: libkrbn_connected_devices_get_is_keyboard(libkrbnConnectedDevices, i), isPointingDevice: libkrbn_connected_devices_get_is_pointing_device( libkrbnConnectedDevices, i), diff --git a/src/apps/share/swift/LibKrbn/Models/ConnectedDevice.swift b/src/apps/share/swift/LibKrbn/Models/ConnectedDevice.swift index eb43168be..fbda7eaeb 100644 --- a/src/apps/share/swift/LibKrbn/Models/ConnectedDevice.swift +++ b/src/apps/share/swift/LibKrbn/Models/ConnectedDevice.swift @@ -9,6 +9,7 @@ extension LibKrbn { let transport: String let vendorId: UInt64 let productId: UInt64 + let deviceAddress: String let isKeyboard: Bool let isPointingDevice: Bool let isBuiltInKeyboard: Bool @@ -25,6 +26,7 @@ extension LibKrbn { transport: String, vendorId: UInt64, productId: UInt64, + deviceAddress: UnsafePointer, isKeyboard: Bool, isPointingDevice: Bool, isBuiltInKeyboard: Bool, @@ -38,6 +40,7 @@ extension LibKrbn { self.transport = transport self.vendorId = vendorId self.productId = productId + self.deviceAddress = String(cString: deviceAddress) self.isKeyboard = isKeyboard self.isPointingDevice = isPointingDevice self.isBuiltInKeyboard = isBuiltInKeyboard @@ -49,6 +52,7 @@ extension LibKrbn { capacity: 1) libkrbnDeviceIdentifiers.pointee.vendor_id = vendorId libkrbnDeviceIdentifiers.pointee.product_id = productId + libkrbnDeviceIdentifiers.pointee.device_address = deviceAddress libkrbnDeviceIdentifiers.pointee.is_keyboard = isKeyboard libkrbnDeviceIdentifiers.pointee.is_pointing_device = isPointingDevice } diff --git a/src/lib/libkrbn/include/libkrbn/impl/libkrbn_cpp.hpp b/src/lib/libkrbn/include/libkrbn/impl/libkrbn_cpp.hpp index 477de27e9..811c46b54 100644 --- a/src/lib/libkrbn/include/libkrbn/impl/libkrbn_cpp.hpp +++ b/src/lib/libkrbn/include/libkrbn/impl/libkrbn_cpp.hpp @@ -9,6 +9,7 @@ class libkrbn_cpp final { static krbn::device_identifiers make_device_identifiers(const libkrbn_device_identifiers& device_identifiers) { krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(device_identifiers.vendor_id), pqrs::hid::product_id::value_t(device_identifiers.product_id), + device_identifiers.device_address ? std::string(device_identifiers.device_address) : "", device_identifiers.is_keyboard, device_identifiers.is_pointing_device); return identifiers; diff --git a/src/lib/libkrbn/include/libkrbn/libkrbn.h b/src/lib/libkrbn/include/libkrbn/libkrbn.h index 1bdd5dfd4..97714506d 100644 --- a/src/lib/libkrbn/include/libkrbn/libkrbn.h +++ b/src/lib/libkrbn/include/libkrbn/libkrbn.h @@ -12,6 +12,7 @@ extern "C" { typedef struct { uint64_t vendor_id; uint64_t product_id; + const char* device_address; bool is_keyboard; bool is_pointing_device; } libkrbn_device_identifiers; @@ -247,6 +248,7 @@ bool libkrbn_connected_devices_get_device_identifiers(libkrbn_connected_devices* libkrbn_device_identifiers* device_identifiers); uint64_t libkrbn_connected_devices_get_vendor_id(libkrbn_connected_devices* p, size_t index); uint64_t libkrbn_connected_devices_get_product_id(libkrbn_connected_devices* p, size_t index); +const char* libkrbn_connected_devices_get_device_address(libkrbn_connected_devices* p, size_t index); bool libkrbn_connected_devices_get_is_keyboard(libkrbn_connected_devices* p, size_t index); bool libkrbn_connected_devices_get_is_pointing_device(libkrbn_connected_devices* p, size_t index); bool libkrbn_connected_devices_get_is_built_in_keyboard(libkrbn_connected_devices* p, size_t index); diff --git a/src/lib/libkrbn/src/libkrbn_connected_devices.cpp b/src/lib/libkrbn/src/libkrbn_connected_devices.cpp index b10452aa3..73172402e 100644 --- a/src/lib/libkrbn/src/libkrbn_connected_devices.cpp +++ b/src/lib/libkrbn/src/libkrbn_connected_devices.cpp @@ -81,6 +81,16 @@ uint64_t libkrbn_connected_devices_get_product_id(libkrbn_connected_devices* p, return 0; } +const char* libkrbn_connected_devices_get_device_address(libkrbn_connected_devices* p, size_t index) { + if (auto c = reinterpret_cast(p)) { + const auto& devices = c->get_connected_devices().get_devices(); + if (index < devices.size()) { + return devices[index].get_identifiers().get_device_address().c_str(); + } + } + return nullptr; +} + bool libkrbn_connected_devices_get_is_keyboard(libkrbn_connected_devices* p, size_t index) { if (auto c = reinterpret_cast(p)) { const auto& devices = c->get_connected_devices().get_devices(); diff --git a/src/share/device_properties.hpp b/src/share/device_properties.hpp index 33c60fb33..c609cc4ea 100644 --- a/src/share/device_properties.hpp +++ b/src/share/device_properties.hpp @@ -26,6 +26,7 @@ class device_properties final { product_ = hid_device.find_product(); serial_number_ = hid_device.find_serial_number(); transport_ = hid_device.find_transport(); + device_address_ = hid_device.find_device_address(); is_keyboard_ = iokit_utility::is_keyboard(hid_device); is_pointing_device_ = iokit_utility::is_pointing_device(hid_device); @@ -138,6 +139,9 @@ class device_properties final { if (transport_) { json["transport"] = *transport_; } + if (device_address_) { + json["device_address"] = *device_address_; + } if (is_keyboard_) { json["is_keyboard"] = *is_keyboard_; } @@ -225,6 +229,16 @@ class device_properties final { return *this; } + std::optional get_device_address(void) const { + return device_address_; + } + + device_properties& set_device_address(const std::string& value) { + device_address_ = value; + update_device_identifiers(); + return *this; + } + std::optional get_device_id(void) const { return device_id_; } @@ -341,6 +355,7 @@ class device_properties final { device_identifiers_ = std::make_shared( vendor_id_.value_or(pqrs::hid::vendor_id::value_t(0)), product_id_.value_or(pqrs::hid::product_id::value_t(0)), + device_address_.value_or(""), is_keyboard_.value_or(false), is_pointing_device_.value_or(false)); } @@ -353,6 +368,7 @@ class device_properties final { std::optional product_; std::optional serial_number_; std::optional transport_; + std::optional device_address_; std::optional is_keyboard_; std::optional is_pointing_device_; std::optional is_built_in_keyboard_; diff --git a/src/share/manipulator/conditions/device.hpp b/src/share/manipulator/conditions/device.hpp index 6875b50ed..311151af0 100644 --- a/src/share/manipulator/conditions/device.hpp +++ b/src/share/manipulator/conditions/device.hpp @@ -123,6 +123,7 @@ class device final : public base { std::optional vendor_id; std::optional product_id; std::optional location_id; + std::optional device_address; std::optional is_keyboard; std::optional is_pointing_device; std::optional is_touch_bar; @@ -132,6 +133,7 @@ class device final : public base { return vendor_id || product_id || location_id || + device_address || is_keyboard || is_pointing_device || is_touch_bar || @@ -154,6 +156,9 @@ class device final : public base { if (location_id && location_id != device_properties.get_location_id().value_or(krbn::location_id(0))) { return false; } + if (device_address && device_address != device_properties.get_device_address().value_or("")) { + return false; + } if (is_keyboard && is_keyboard != device_properties.get_is_keyboard().value_or(false)) { return false; } @@ -199,6 +204,11 @@ class device final : public base { d.location_id = location_id(value.get()); + } else if (key == "device_address") { + pqrs::json::requires_string(value, "identifiers entry `device_address`"); + + d.device_address = value.get(); + } else if (key == "is_keyboard") { pqrs::json::requires_boolean(value, "identifiers entry `is_keyboard`"); diff --git a/src/share/types/device_identifiers.hpp b/src/share/types/device_identifiers.hpp index f426fea4a..a6f5799f2 100644 --- a/src/share/types/device_identifiers.hpp +++ b/src/share/types/device_identifiers.hpp @@ -10,15 +10,18 @@ class device_identifiers final { public: device_identifiers(void) : vendor_id_(pqrs::hid::vendor_id::value_t(0)), product_id_(pqrs::hid::product_id::value_t(0)), + device_address_(""), is_keyboard_(false), is_pointing_device_(false) { } device_identifiers(pqrs::hid::vendor_id::value_t vendor_id, pqrs::hid::product_id::value_t product_id, + std::string device_address, bool is_keyboard, bool is_pointing_device) : vendor_id_(vendor_id), product_id_(product_id), + device_address_(device_address), is_keyboard_(is_keyboard), is_pointing_device_(is_pointing_device) { } @@ -47,6 +50,14 @@ class device_identifiers final { product_id_ = value; } + const std::string& get_device_address(void) const { + return device_address_; + } + + void set_device_address(std::string value) { + device_address_ = value; + } + bool get_is_keyboard(void) const { return is_keyboard_; } @@ -71,6 +82,7 @@ class device_identifiers final { bool operator==(const device_identifiers& other) const { return vendor_id_ == other.vendor_id_ && product_id_ == other.product_id_ && + device_address_ == other.device_address_ && is_keyboard_ == other.is_keyboard_ && is_pointing_device_ == other.is_pointing_device_; } @@ -79,6 +91,7 @@ class device_identifiers final { nlohmann::json json_; pqrs::hid::vendor_id::value_t vendor_id_; pqrs::hid::product_id::value_t product_id_; + std::string device_address_; bool is_keyboard_; bool is_pointing_device_; }; @@ -87,6 +100,7 @@ inline void to_json(nlohmann::json& json, const device_identifiers& value) { json = value.get_json(); json["vendor_id"] = type_safe::get(value.get_vendor_id()); json["product_id"] = type_safe::get(value.get_product_id()); + json["device_address"] = value.get_device_address(); json["is_keyboard"] = value.get_is_keyboard(); json["is_pointing_device"] = value.get_is_pointing_device(); } @@ -105,6 +119,11 @@ inline void from_json(const nlohmann::json& json, device_identifiers& value) { value.set_product_id(v.get()); + } else if (k == "device_address") { + pqrs::json::requires_string(v, "`" + k + "`"); + + value.set_device_address(v.get()); + } else if (k == "is_keyboard") { pqrs::json::requires_boolean(v, "`" + k + "`"); diff --git a/tests/src/connected_devices/json/connected_devices.json b/tests/src/connected_devices/json/connected_devices.json index 990381c57..213ce96a0 100644 --- a/tests/src/connected_devices/json/connected_devices.json +++ b/tests/src/connected_devices/json/connected_devices.json @@ -6,6 +6,7 @@ "transport": "USB" }, "identifiers": { + "device_address": "", "is_keyboard": true, "is_pointing_device": false, "product_id": 5678, @@ -22,6 +23,7 @@ "transport": "USB" }, "identifiers": { + "device_address": "", "is_keyboard": false, "is_pointing_device": true, "product_id": 5679, @@ -38,6 +40,7 @@ "transport": "USB" }, "identifiers": { + "device_address": "", "is_keyboard": false, "is_pointing_device": true, "product_id": 6789, @@ -54,6 +57,7 @@ "transport": "Bluetooth" }, "identifiers": { + "device_address": "ec-ba-73-21-e6-f4", "is_keyboard": true, "is_pointing_device": false, "product_id": 678, @@ -70,6 +74,7 @@ "transport": "Bluetooth" }, "identifiers": { + "device_address": "ec-ba-73-21-e6-f4", "is_keyboard": false, "is_pointing_device": true, "product_id": 678, @@ -86,10 +91,11 @@ "transport": "Bluetooth" }, "identifiers": { + "device_address": "ec-ba-73-21-e6-f5", "is_keyboard": true, "is_pointing_device": false, - "product_id": 678, - "vendor_id": 1234 + "product_id": 0, + "vendor_id": 0 }, "is_built_in_keyboard": false, "is_built_in_touch_bar": true, diff --git a/tests/src/connected_devices/json/ill_formed_name_expected.json b/tests/src/connected_devices/json/ill_formed_name_expected.json index a7744c05e..f0ea0663e 100644 --- a/tests/src/connected_devices/json/ill_formed_name_expected.json +++ b/tests/src/connected_devices/json/ill_formed_name_expected.json @@ -6,6 +6,7 @@ "transport": "USB" }, "identifiers": { + "device_address": "", "is_keyboard": true, "is_pointing_device": false, "product_id": 5678, diff --git a/tests/src/connected_devices/src/connected_devices_test.hpp b/tests/src/connected_devices/src/connected_devices_test.hpp index 6b452614d..e68e3f23e 100644 --- a/tests/src/connected_devices/src/connected_devices_test.hpp +++ b/tests/src/connected_devices/src/connected_devices_test.hpp @@ -20,6 +20,7 @@ void run_connected_devices_test(void) { "USB"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), + "", true, false); krbn::connected_devices::details::device device(descriptions, @@ -35,6 +36,7 @@ void run_connected_devices_test(void) { "USB"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), + "", true, false); krbn::connected_devices::details::device device(descriptions, @@ -50,6 +52,7 @@ void run_connected_devices_test(void) { "USB"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(2345), pqrs::hid::product_id::value_t(6789), + "", false, true); krbn::connected_devices::details::device device(descriptions, @@ -65,6 +68,7 @@ void run_connected_devices_test(void) { "USB"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5679), + "", false, true); krbn::connected_devices::details::device device(descriptions, @@ -81,6 +85,7 @@ void run_connected_devices_test(void) { "Bluetooth"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(123), pqrs::hid::product_id::value_t(678), + "ec-ba-73-21-e6-f4", false, true); krbn::connected_devices::details::device device(descriptions, @@ -96,6 +101,7 @@ void run_connected_devices_test(void) { "Bluetooth"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(123), pqrs::hid::product_id::value_t(678), + "ec-ba-73-21-e6-f4", true, false); krbn::connected_devices::details::device device(descriptions, @@ -105,12 +111,14 @@ void run_connected_devices_test(void) { false); connected_devices.push_back_device(device); } + // product5 is a bluetooth HID device that has no vendor_id/product_id { krbn::connected_devices::details::descriptions descriptions("manufacturer1", "product5", "Bluetooth"); - krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), - pqrs::hid::product_id::value_t(678), + krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(0), + pqrs::hid::product_id::value_t(0), + "ec-ba-73-21-e6-f5", true, false); krbn::connected_devices::details::device device(descriptions, @@ -125,10 +133,15 @@ void run_connected_devices_test(void) { expect(connected_devices.get_devices().size() == 6); expect(connected_devices.get_devices()[0].get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(connected_devices.get_devices()[0].get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(5678)); + expect(connected_devices.get_devices()[0].get_identifiers().get_device_address() == ""); expect(connected_devices.get_devices()[1].get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(connected_devices.get_devices()[1].get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(5679)); + expect(connected_devices.get_devices()[0].get_identifiers().get_device_address() == ""); expect(connected_devices.get_devices()[2].get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(2345)); expect(connected_devices.get_devices()[2].get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(6789)); + expect(connected_devices.get_devices()[0].get_identifiers().get_device_address() == ""); + expect(connected_devices.get_devices()[4].get_identifiers().get_device_address() == "ec-ba-73-21-e6-f4"); + expect(connected_devices.get_devices()[5].get_identifiers().get_device_address() == "ec-ba-73-21-e6-f5"); std::ifstream ifs("json/connected_devices.json"); @@ -181,6 +194,7 @@ void run_connected_devices_test(void) { "USB"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), + "", true, false); krbn::connected_devices::details::device device(descriptions, diff --git a/tests/src/connected_devices/src/device_test.hpp b/tests/src/connected_devices/src/device_test.hpp index 23a6f556e..217947883 100644 --- a/tests/src/connected_devices/src/device_test.hpp +++ b/tests/src/connected_devices/src/device_test.hpp @@ -12,6 +12,7 @@ void run_device_test(void) { "USB"); krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), + "", true, false); krbn::connected_devices::details::device device(descriptions, @@ -53,6 +54,10 @@ void run_device_test(void) { "product_id", 5678, }, + { + "device_address", + "", + }, { "is_keyboard", true, @@ -130,6 +135,7 @@ void run_device_test(void) { expect(device1.get_descriptions().get_product() == ""); expect(device1.get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(0)); expect(device1.get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(0)); + expect(device1.get_identifiers().get_device_address() == ""); expect(device1.get_identifiers().get_is_keyboard() == false); expect(device1.get_identifiers().get_is_pointing_device() == false); expect(device1.get_is_built_in_keyboard() == false); @@ -157,6 +163,7 @@ void run_device_test(void) { expect(device.get_descriptions().get_product() == ""); expect(device.get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(0)); expect(device.get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(0)); + expect(device.get_identifiers().get_device_address() == ""); expect(device.get_identifiers().get_is_keyboard() == false); expect(device.get_identifiers().get_is_pointing_device() == false); expect(device.get_is_built_in_keyboard() == false); @@ -170,6 +177,7 @@ void run_device_test(void) { .set_product("product") .set(pqrs::hid::vendor_id::value_t(1234)) .set(pqrs::hid::product_id::value_t(5678)) + .set_device_address("ec-ba-73-21-e6-f4") .set_is_keyboard(true); { @@ -179,6 +187,7 @@ void run_device_test(void) { expect(device.get_descriptions().get_product() == "product"); expect(device.get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(device.get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(5678)); + expect(device.get_identifiers().get_device_address() == "ec-ba-73-21-e6-f4"); expect(device.get_identifiers().get_is_keyboard() == true); expect(device.get_identifiers().get_is_pointing_device() == false); expect(device.get_is_built_in_keyboard() == false); diff --git a/tests/src/core_configuration/json/to_json_example.json b/tests/src/core_configuration/json/to_json_example.json index 8339cb0f5..6f5c0210e 100644 --- a/tests/src/core_configuration/json/to_json_example.json +++ b/tests/src/core_configuration/json/to_json_example.json @@ -130,6 +130,7 @@ } ], "identifiers": { + "device_address": "", "is_keyboard": true, "is_pointing_device": false, "product_id": 50475, @@ -155,6 +156,7 @@ "disable_built_in_keyboard_if_exists": true, "fn_function_keys": [], "identifiers": { + "device_address": "", "is_keyboard": true, "is_pointing_device": false, "product_id": 610, @@ -190,6 +192,7 @@ } ], "identifiers": { + "device_address": "", "is_keyboard": true, "is_pointing_device": false, "product_id": 50475, diff --git a/tests/src/core_configuration/src/core_configuration_test.hpp b/tests/src/core_configuration/src/core_configuration_test.hpp index 73600c24e..7e724ce19 100644 --- a/tests/src/core_configuration/src/core_configuration_test.hpp +++ b/tests/src/core_configuration/src/core_configuration_test.hpp @@ -282,10 +282,12 @@ void run_core_configuration_test(void) { expect(profile.get_device_ignore(krbn::device_identifiers(pqrs::hid::vendor_id::value_t(4176), pqrs::hid::product_id::value_t(1031), + "", true, false)) == true); expect(profile.get_device_ignore(krbn::device_identifiers(pqrs::hid::vendor_id::value_t(0x05ac), pqrs::hid::product_id::value_t(0x262), + "", true, false)) == false); } @@ -539,12 +541,14 @@ void run_core_configuration_test(void) { { krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1112), pqrs::hid::product_id::value_t(2222), + "ec-ba-73-21-e6-f5", false, true); profile.set_device_disable_built_in_keyboard_if_exists(identifiers, true); expect(profile.get_devices().size() == 5); expect((profile.get_devices())[4].get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(1112)); expect((profile.get_devices())[4].get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(2222)); + expect((profile.get_devices())[4].get_identifiers().get_device_address() == "ec-ba-73-21-e6-f5"); expect((profile.get_devices())[4].get_identifiers().get_is_keyboard() == false); expect((profile.get_devices())[4].get_identifiers().get_is_pointing_device() == true); expect((profile.get_devices())[4].get_ignore() == true); @@ -627,6 +631,10 @@ void run_core_configuration_test(void) { "product_id", 5678, }, + { + "device_address", + "ec-ba-73-21-e6-f5" + }, { "is_keyboard", true, @@ -796,6 +804,10 @@ void run_core_configuration_test(void) { "product_id", 5678, }, + { + "device_address", + "ec-ba-73-21-e6-f5" + }, { "is_keyboard", true, diff --git a/tests/src/core_configuration/src/device_test.hpp b/tests/src/core_configuration/src/device_test.hpp index b7691cbe8..1a67b162b 100644 --- a/tests/src/core_configuration/src/device_test.hpp +++ b/tests/src/core_configuration/src/device_test.hpp @@ -21,28 +21,32 @@ void run_device_test(void) { nlohmann::json json({ {"vendor_id", 1234}, {"product_id", 5678}, + {"device_address", "ec-ba-73-21-e6-f5"}, {"is_keyboard", true}, {"is_pointing_device", true}, }); auto identifiers = json.get(); expect(identifiers.get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(identifiers.get_product_id() == pqrs::hid::product_id::value_t(5678)); + expect(identifiers.get_device_address() == "ec-ba-73-21-e6-f5"); expect(identifiers.get_is_keyboard() == true); expect(identifiers.get_is_pointing_device() == true); } // construct with vendor_id, product_id, ... { - krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), true, false); + krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), "ec-ba-73-21-e6-f5", true, false); expect(identifiers.get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(identifiers.get_product_id() == pqrs::hid::product_id::value_t(5678)); + expect(identifiers.get_device_address() == "ec-ba-73-21-e6-f5"); expect(identifiers.get_is_keyboard() == true); expect(identifiers.get_is_pointing_device() == false); } { - krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(4321), pqrs::hid::product_id::value_t(8765), false, true); + krbn::device_identifiers identifiers(pqrs::hid::vendor_id::value_t(4321), pqrs::hid::product_id::value_t(8765), "", false, true); expect(identifiers.get_vendor_id() == pqrs::hid::vendor_id::value_t(4321)); expect(identifiers.get_product_id() == pqrs::hid::product_id::value_t(8765)); + expect(identifiers.get_device_address() == ""); expect(identifiers.get_is_keyboard() == false); expect(identifiers.get_is_pointing_device() == true); } @@ -55,6 +59,7 @@ void run_device_test(void) { nlohmann::json expected({ {"vendor_id", 0}, {"product_id", 0}, + {"device_address", ""}, {"is_keyboard", false}, {"is_pointing_device", false}, }); @@ -70,6 +75,7 @@ void run_device_test(void) { {"dummy", {{"keep_me", true}}}, {"vendor_id", 0}, {"product_id", 0}, + {"device_address", ""}, {"is_keyboard", false}, {"is_pointing_device", true}, }); @@ -84,6 +90,7 @@ void run_device_test(void) { krbn::core_configuration::details::device device(json); expect(device.get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(0)); expect(device.get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(0)); + expect(device.get_identifiers().get_device_address() == ""); expect(device.get_identifiers().get_is_keyboard() == false); expect(device.get_identifiers().get_is_pointing_device() == false); expect(device.get_ignore() == false); @@ -98,6 +105,7 @@ void run_device_test(void) { {"identifiers", { {"vendor_id", 1234}, {"product_id", 5678}, + {"device_address", "ec-ba-73-21-e6-f5"}, {"is_keyboard", true}, {"is_pointing_device", true}, }}, @@ -109,6 +117,7 @@ void run_device_test(void) { krbn::core_configuration::details::device device(json); expect(device.get_identifiers().get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(device.get_identifiers().get_product_id() == pqrs::hid::product_id::value_t(5678)); + expect(device.get_identifiers().get_device_address() == "ec-ba-73-21-e6-f5"); expect(device.get_identifiers().get_is_keyboard() == true); expect(device.get_identifiers().get_is_pointing_device() == true); expect(device.get_ignore() == true); @@ -238,6 +247,10 @@ void run_device_test(void) { "product_id", 0, }, + { + "device_address", + "" + }, { "is_keyboard", false, @@ -293,6 +306,10 @@ void run_device_test(void) { "product_id", 0, }, + { + "device_address", + "" + }, { "is_keyboard", true, diff --git a/tests/src/manipulator/src/manipulator_factory_test.hpp b/tests/src/manipulator/src/manipulator_factory_test.hpp index d95b9c68b..7c7102d0f 100644 --- a/tests/src/manipulator/src/manipulator_factory_test.hpp +++ b/tests/src/manipulator/src/manipulator_factory_test.hpp @@ -102,13 +102,13 @@ void run_manipulator_factory_test(void) { krbn::core_configuration::details::device device(json); auto device_id_1234_5678_keyboard = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), "", std::nullopt, true, false); auto device_id_1234_5678_mouse = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), std::nullopt, false, true); + pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), "", std::nullopt, false, true); auto device_id_1234_5000_keyboard = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5000), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5000), "", std::nullopt, true, false); auto c = krbn::manipulator::manipulator_factory::make_device_if_condition(device); diff --git a/tests/src/manipulator_conditions/json/device_if.jsonc b/tests/src/manipulator_conditions/json/device_if.jsonc index 798744215..faa709afb 100644 --- a/tests/src/manipulator_conditions/json/device_if.jsonc +++ b/tests/src/manipulator_conditions/json/device_if.jsonc @@ -14,6 +14,9 @@ "description": "any product_id", "vendor_id": 1099 }, + { + "device_address": "aa-bb-cc-dd-ee-ff" + }, { // Empty identifier is ignored. } diff --git a/tests/src/manipulator_conditions/src/device_exists_test.hpp b/tests/src/manipulator_conditions/src/device_exists_test.hpp index 17c0e5b4d..b40b6fe17 100644 --- a/tests/src/manipulator_conditions/src/device_exists_test.hpp +++ b/tests/src/manipulator_conditions/src/device_exists_test.hpp @@ -15,7 +15,7 @@ void run_device_exists_test(void) { auto& environment = manipulator_conditions_helper.get_manipulator_environment(); auto device_id_8888_9999 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(8888), pqrs::hid::product_id::value_t(9999), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(8888), pqrs::hid::product_id::value_t(9999), "", std::nullopt, true, false); { auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_8888_9999); @@ -23,7 +23,7 @@ void run_device_exists_test(void) { } manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, true, false); { auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_8888_9999); @@ -39,7 +39,7 @@ void run_device_exists_test(void) { auto& environment = manipulator_conditions_helper.get_manipulator_environment(); auto device_id_8888_9999 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(8888), pqrs::hid::product_id::value_t(9999), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(8888), pqrs::hid::product_id::value_t(9999), "", std::nullopt, true, false); { auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_8888_9999); @@ -47,7 +47,7 @@ void run_device_exists_test(void) { } manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, true, false); { auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_8888_9999); diff --git a/tests/src/manipulator_conditions/src/device_test.hpp b/tests/src/manipulator_conditions/src/device_test.hpp index 102fc19f8..cc144a864 100644 --- a/tests/src/manipulator_conditions/src/device_test.hpp +++ b/tests/src/manipulator_conditions/src/device_test.hpp @@ -12,49 +12,49 @@ void run_device_test(void) { auto& environment = manipulator_conditions_helper.get_manipulator_environment(); auto device_id_8888_9999 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(8888), pqrs::hid::product_id::value_t(9999), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(8888), pqrs::hid::product_id::value_t(9999), "", std::nullopt, true, false); auto device_id_1000_2000 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, true, false); auto device_id_1000_2001 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2001), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2001), "", std::nullopt, true, false); auto device_id_1001_2000 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1001), pqrs::hid::product_id::value_t(2000), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1001), pqrs::hid::product_id::value_t(2000), "", std::nullopt, true, false); auto device_id_1001_2001 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1001), pqrs::hid::product_id::value_t(2001), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1001), pqrs::hid::product_id::value_t(2001), "", std::nullopt, true, false); auto device_id_1099_9999 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1099), pqrs::hid::product_id::value_t(9999), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1099), pqrs::hid::product_id::value_t(9999), "", std::nullopt, true, false); auto device_id_0000_0000 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(0), pqrs::hid::product_id::value_t(0), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(0), pqrs::hid::product_id::value_t(0), "aa-bb-cc-dd-ee-ff", std::nullopt, true, false); auto device_id_nullopt_nullopt = manipulator_conditions_helper.prepare_device( - std::nullopt, std::nullopt, std::nullopt, true, false); + std::nullopt, std::nullopt, std::nullopt, std::nullopt, true, false); auto device_id_1000_2000_tt = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, true, true); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, true, true); auto device_id_1000_2000_tf = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, true, false); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, true, false); auto device_id_1000_2000_ft = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, false, true); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, false, true); auto device_id_1000_2000_ff = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, false, false); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", std::nullopt, false, false); auto device_id_1000_2000_3000 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), krbn::location_id(3000), std::nullopt, std::nullopt); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", krbn::location_id(3000), std::nullopt, std::nullopt); auto device_id_1000_2000_none = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, std::nullopt, std::nullopt); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), std::nullopt, std::nullopt, std::nullopt, std::nullopt); auto device_id_1000_2000_4000 = manipulator_conditions_helper.prepare_device( - pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), krbn::location_id(4000), std::nullopt, std::nullopt); + pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", krbn::location_id(4000), std::nullopt, std::nullopt); { actual_examples_helper helper("device_if.jsonc"); @@ -83,6 +83,10 @@ void run_device_test(void) { auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_1099_9999); expect(helper.get_condition_manager().is_fulfilled(e, environment) == true); } + { + auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_0000_0000); + expect(helper.get_condition_manager().is_fulfilled(e, environment) == true); + } } { actual_examples_helper helper("device_unless.jsonc"); @@ -214,14 +218,14 @@ void run_device_test(void) { } { manipulator_conditions_helper.get_core_configuration()->get_selected_profile().set_device_treat_as_built_in_keyboard( - krbn::device_identifiers(pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), true, false), + krbn::device_identifiers(pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", true, false), true); auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_1000_2000); expect(condition.is_fulfilled(e, environment) == true); } { manipulator_conditions_helper.get_core_configuration()->get_selected_profile().set_device_treat_as_built_in_keyboard( - krbn::device_identifiers(pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), true, false), + krbn::device_identifiers(pqrs::hid::vendor_id::value_t(1000), pqrs::hid::product_id::value_t(2000), "", true, false), false); auto e = manipulator_conditions_helper.make_event_queue_entry(device_id_1000_2000); expect(condition.is_fulfilled(e, environment) == false); diff --git a/tests/src/share/manipulator_conditions_helper.hpp b/tests/src/share/manipulator_conditions_helper.hpp index 627696ade..686b0c06e 100644 --- a/tests/src/share/manipulator_conditions_helper.hpp +++ b/tests/src/share/manipulator_conditions_helper.hpp @@ -30,6 +30,7 @@ class manipulator_conditions_helper final { krbn::device_id prepare_device(std::optional vendor_id, std::optional product_id, + std::optional device_address, std::optional location_id, std::optional is_keyboard, std::optional is_pointing_device) { @@ -43,6 +44,9 @@ class manipulator_conditions_helper final { if (product_id) { properties.set(*product_id); } + if (device_address) { + properties.set_device_address(*device_address); + } if (location_id) { properties.set(*location_id); } diff --git a/tests/src/types/src/device_identifiers_test.hpp b/tests/src/types/src/device_identifiers_test.hpp index 5deedf7b7..bd2fd794b 100644 --- a/tests/src/types/src/device_identifiers_test.hpp +++ b/tests/src/types/src/device_identifiers_test.hpp @@ -9,6 +9,7 @@ void run_device_identifiers_test(void) { { krbn::device_identifiers di(pqrs::hid::vendor_id::value_t(1234), pqrs::hid::product_id::value_t(5678), + "", true, false); expect(di.is_apple() == false); @@ -16,6 +17,7 @@ void run_device_identifiers_test(void) { { krbn::device_identifiers di(pqrs::hid::vendor_id::value_t(1452), pqrs::hid::product_id::value_t(610), + "", true, false); expect(di.is_apple() == true); @@ -25,6 +27,7 @@ void run_device_identifiers_test(void) { auto di = json.get(); expect(di.get_vendor_id() == pqrs::hid::vendor_id::value_t(0)); expect(di.get_product_id() == pqrs::hid::product_id::value_t(0)); + expect(di.get_device_address() == ""); expect(di.get_is_keyboard() == false); expect(di.get_is_pointing_device() == false); } @@ -32,6 +35,7 @@ void run_device_identifiers_test(void) { auto json = nlohmann::json::object({ {"vendor_id", 1234}, {"product_id", 5678}, + {"device_address", "aa-bb-cc-dd-ee-ff"}, {"is_keyboard", true}, {"is_pointing_device", false}, {"dummy key", "dummy value"}, @@ -40,6 +44,7 @@ void run_device_identifiers_test(void) { auto di = json.get(); expect(di.get_vendor_id() == pqrs::hid::vendor_id::value_t(1234)); expect(di.get_product_id() == pqrs::hid::product_id::value_t(5678)); + expect(di.get_device_address() == "aa-bb-cc-dd-ee-ff"); expect(di.get_is_keyboard() == true); expect(di.get_is_pointing_device() == false); expect(nlohmann::json(di) == json);