diff --git a/internal/platform/implementation/linux/bluetooth_classic_medium.cc b/internal/platform/implementation/linux/bluetooth_classic_medium.cc index 2115684f..f8552491 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/linux/bluetooth_classic_medium.cc @@ -7,6 +7,7 @@ #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "internal/platform/implementation/bluetooth_classic.h" +#include "internal/platform/implementation/linux/bluetooth_adapter.h" #include "internal/platform/implementation/linux/bluetooth_bluez_profile.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" #include "internal/platform/implementation/linux/bluetooth_classic_medium.h" @@ -18,45 +19,45 @@ namespace nearby { namespace linux { -BluetoothClassicMedium::BluetoothClassicMedium(sdbus::IConnection &system_bus, - absl::string_view adapter) - : devices_(system_bus, absl::Substitute("/org/bluez/$0/", adapter), - observers_), - profile_manager_(system_bus) { - bluez_adapter_proxy_ = sdbus::createProxy( - "org.bluez", absl::Substitute("/org/bluez/$0/", adapter)); - bluez_adapter_proxy_->finishRegistration(); - bluez_proxy_ = sdbus::createProxy("org.bluez", "/"); - bluez_proxy_->finishRegistration(); +BluetoothClassicMedium::BluetoothClassicMedium( + sdbus::IConnection &system_bus, + const sdbus::ObjectPath &adapter_object_path) + : ProxyInterfaces(system_bus, "org.bluez", "/"), + adapter_( + std::make_unique(system_bus, adapter_object_path)), + devices_(std::make_unique( + system_bus, adapter_object_path, observers_)), + profile_manager_( + std::make_unique(system_bus, *devices_)) { + registerProxy(); } -void BluetoothClassicMedium::onInterfacesAdded(sdbus::Signal &signal) { - sdbus::ObjectPath object; - signal >> object; +BluetoothClassicMedium::~BluetoothClassicMedium() { unregisterProxy(); } +void BluetoothClassicMedium::onInterfacesAdded( + const sdbus::ObjectPath &object, + const std::map> + &interfacesAndProperties) { NEARBY_LOGS(VERBOSE) << __func__ << "New intefaces added at " << object; - auto path_prefix = - absl::Substitute("$0/dev_", bluez_adapter_proxy_->getObjectPath()); + auto path_prefix = absl::Substitute("$0/dev_", adapter_->getObjectPath()); if (object.find(path_prefix) != 0) { return; } - if (devices_.get_device_by_path(object).has_value()) { + if (devices_->get_device_by_path(object).has_value()) { // Device already exists. return; } - std::map> interfaces; - signal >> interfaces; - - for (auto it = interfaces.begin(); it != interfaces.end(); it++) { + for (auto it = interfacesAndProperties.begin(); + it != interfacesAndProperties.end(); it++) { auto interface = it->first; if (interface == "org.bluez.Device1") { - NEARBY_LOGS(INFO) << __func__ << "Encountered new device at " << object; + NEARBY_LOGS(INFO) << __func__ << ": Encountered new device at " << object; - auto &device = devices_.add_new_device(object); + auto &device = devices_->add_new_device(object); discovery_cb_lock_.ReaderLock(); if (discovery_cb_.has_value() && @@ -72,21 +73,16 @@ void BluetoothClassicMedium::onInterfacesAdded(sdbus::Signal &signal) { } } -void BluetoothClassicMedium::onInterfacesRemoved(sdbus::Signal &signal) { - sdbus::ObjectPath object; - signal >> object; - +void BluetoothClassicMedium::onInterfacesRemoved( + const sdbus::ObjectPath &object, + const std::vector &interfaces) { NEARBY_LOGS(VERBOSE) << __func__ << ": Intefaces removed at " << object; - auto path_prefix = - absl::Substitute("$0/dev_", bluez_adapter_proxy_->getObjectPath()); + auto path_prefix = absl::Substitute("$0/dev_", adapter_->getObjectPath()); if (object.find(path_prefix) != 0) { return; } - std::vector interfaces; - signal >> interfaces; - for (auto &interface : interfaces) { if (interface == bluez::DEVICE_INTERFACE) { @@ -122,23 +118,12 @@ bool BluetoothClassicMedium::StartDiscovery( discovery_cb_ = std::move(discovery_callback); discovery_cb_lock_.Unlock(); - NEARBY_LOGS(VERBOSE) << __func__ - << ": Subscribing to InterfacesAdded on / at org.bluez"; - - bluez_proxy_->registerSignalHandler( - "org.freedesktop.DBus.ObjectManager", "InterfacesAdded", - [this](sdbus::Signal &signal) { this->onInterfacesAdded(signal); }); - bluez_proxy_->registerSignalHandler( - "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved", - [this](sdbus::Signal &signal) { this->onInterfacesRemoved(signal); }); - try { NEARBY_LOGS(INFO) << __func__ << ": Starting discovery on " - << bluez_adapter_proxy_->getObjectPath(); - bluez_adapter_proxy_->callMethod("StartDiscovery") - .onInterface(bluez::ADAPTER_INTERFACE); + << adapter_->getObjectPath(); + adapter_->StartDiscovery(); } catch (const sdbus::Error &e) { - BLUEZ_LOG_METHOD_CALL_ERROR(bluez_adapter_proxy_, "StartDiscovery", e); + BLUEZ_LOG_METHOD_CALL_ERROR(adapter_, "StartDiscovery", e); return false; } @@ -146,24 +131,15 @@ bool BluetoothClassicMedium::StartDiscovery( } bool BluetoothClassicMedium::StopDiscovery() { - NEARBY_LOGS(VERBOSE) - << __func__ << ": Unsubscribing to InterfacesAdded on / at org.bluez"; - bluez_proxy_->unregisterSignalHandler("org.freedesktop.DBus.ObjectManager", - "InterfacesAdded"); - bluez_proxy_->unregisterSignalHandler("org.freedesktop.DBus.ObjectManager", - "InterfacesRemoved"); try { NEARBY_LOGS(INFO) << __func__ << "Stopping discovery on " - << bluez_adapter_proxy_->getObjectPath(); - bluez_adapter_proxy_->callMethodAsync("StopDiscovery") - .onInterface(bluez::ADAPTER_INTERFACE) - .uponReplyInvoke([this](const sdbus::Error *err) { - this->discovery_cb_lock_.Lock(); - this->discovery_cb_.reset(); - this->discovery_cb_lock_.Unlock(); - }); + << adapter_->getObjectPath(); + + absl::MutexLock l(&this->discovery_cb_lock_); + adapter_->StopDiscovery(); + this->discovery_cb_.reset(); } catch (const sdbus::Error &e) { - BLUEZ_LOG_METHOD_CALL_ERROR(bluez_adapter_proxy_, "StopDiscovery", e); + BLUEZ_LOG_METHOD_CALL_ERROR(adapter_, "StopDiscovery", e); return false; } @@ -175,20 +151,20 @@ BluetoothClassicMedium::ConnectToService(api::BluetoothDevice &remote_device, const std::string &service_uuid, CancellationFlag *cancellation_flag) { auto device_object_path = bluez::device_object_path( - bluez_adapter_proxy_->getObjectPath(), remote_device.GetMacAddress()); - if (!profile_manager_.ProfileRegistered(service_uuid)) { - if (!profile_manager_.Register("", service_uuid)) { + adapter_->getObjectPath(), remote_device.GetMacAddress()); + if (!profile_manager_->ProfileRegistered(service_uuid)) { + if (!profile_manager_->Register("", service_uuid)) { NEARBY_LOGS(ERROR) << __func__ << ": Could not register profile " << service_uuid << " with Bluez"; return nullptr; } } - auto &device = devices_.get_device_by_path(device_object_path).value().get(); + auto &device = devices_->get_device_by_path(device_object_path).value().get(); device.ConnectToProfile(service_uuid); - auto fd = profile_manager_.GetServiceRecordFD(remote_device, service_uuid, - cancellation_flag); + auto fd = profile_manager_->GetServiceRecordFD(remote_device, service_uuid, + cancellation_flag); if (!fd.has_value()) { NEARBY_LOGS(WARNING) << __func__ << ": Failed to get a new connection for profile " @@ -204,8 +180,8 @@ BluetoothClassicMedium::ConnectToService(api::BluetoothDevice &remote_device, std::unique_ptr BluetoothClassicMedium::ListenForService(const std::string &service_name, const std::string &service_uuid) { - if (!profile_manager_.ProfileRegistered(service_uuid)) { - if (!profile_manager_.RegisterProfile(service_name, service_uuid)) { + if (!profile_manager_->ProfileRegistered(service_uuid)) { + if (!profile_manager_->Register(service_name, service_uuid)) { NEARBY_LOGS(ERROR) << __func__ << ": Could not register profile " << service_name << " " << service_uuid << " with Bluez"; @@ -214,7 +190,7 @@ BluetoothClassicMedium::ListenForService(const std::string &service_name, } return std::unique_ptr( - new BluetoothServerSocket(profile_manager_, service_uuid)); + new BluetoothServerSocket(*profile_manager_, service_uuid)); } api::BluetoothDevice * @@ -228,11 +204,9 @@ BluetoothClassicMedium::GetRemoteDevice(const std::string &mac_address) { std::unique_ptr BluetoothClassicMedium::CreatePairing(api::BluetoothDevice &remote_device) { - auto device_object_path = bluez::device_object_path( - bluez_adapter_proxy_->getObjectPath(), remote_device.GetMacAddress()); + auto device = devices_->get_device_by_address(remote_device.GetMacAddress()); return std::unique_ptr( - new BluetoothPairing(bluez_adapter_proxy_->getObjectPath(), remote_device, - bluez_adapter_proxy_->getConnection())); + new BluetoothPairing(*adapter_, *device)); } } // namespace linux diff --git a/internal/platform/implementation/linux/bluetooth_classic_medium.h b/internal/platform/implementation/linux/bluetooth_classic_medium.h index 783cc728..0154b9a2 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_medium.h +++ b/internal/platform/implementation/linux/bluetooth_classic_medium.h @@ -8,12 +8,15 @@ #include #include +#include +#include #include #include #include "absl/synchronization/mutex.h" #include "internal/base/observer_list.h" #include "internal/platform/implementation/bluetooth_classic.h" +#include "internal/platform/implementation/linux/bluetooth_adapter.h" #include "internal/platform/implementation/linux/bluetooth_bluez_profile.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" #include "internal/platform/implementation/linux/bluetooth_devices.h" @@ -22,11 +25,13 @@ namespace nearby { namespace linux { // Container of operations that can be performed over the Bluetooth Classic // medium. -class BluetoothClassicMedium : public api::BluetoothClassicMedium { +class BluetoothClassicMedium + : public api::BluetoothClassicMedium, + sdbus::ProxyInterfaces { public: BluetoothClassicMedium(sdbus::IConnection &system_bus, - absl::string_view adapter); - ~BluetoothClassicMedium() = default; + const sdbus::ObjectPath &adapter_object_path); + ~BluetoothClassicMedium() override; // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery() // @@ -94,20 +99,23 @@ public: get_device_by_address(const std::string &); void remove_device_by_path(const sdbus::ObjectPath &); -private: - void onInterfacesAdded(sdbus::Signal &signal); - void onInterfacesRemoved(sdbus::Signal &signal); +protected: + void onInterfacesAdded( + const sdbus::ObjectPath &objectPath, + const std::map> + &interfacesAndProperties) override; + void onInterfacesRemoved(const sdbus::ObjectPath &objectPath, + const std::vector &interfaces) override; - BluetoothDevices devices_; +private: + std::unique_ptr adapter_; + std::unique_ptr devices_; absl::Mutex discovery_cb_lock_; std::optional discovery_cb_; - ProfileManager profile_manager_; + std::unique_ptr profile_manager_; ObserverList observers_; - - std::unique_ptr bluez_adapter_proxy_; - std::unique_ptr bluez_proxy_; }; } // namespace linux diff --git a/internal/platform/implementation/linux/bluetooth_pairing.cc b/internal/platform/implementation/linux/bluetooth_pairing.cc index 08d893d4..81bdbb89 100644 --- a/internal/platform/implementation/linux/bluetooth_pairing.cc +++ b/internal/platform/implementation/linux/bluetooth_pairing.cc @@ -1,13 +1,13 @@ +#include + #include #include #include #include -#include #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/linux/bluetooth_adapter.h" #include "internal/platform/implementation/linux/bluetooth_pairing.h" -#include "internal/platform/implementation/linux/bluez.h" #include "internal/platform/logging.h" namespace nearby { @@ -48,10 +48,8 @@ void BluetoothPairing::pairing_reply_handler(const sdbus::Error *error) { return; } -BluetoothPairing::BluetoothPairing(const sdbus::ObjectPath &adapter_object_path, - BluetoothDevice &remote_device, - BluetoothAdapter &adapter, - sdbus::IConnection &system_bus) +BluetoothPairing::BluetoothPairing(BluetoothAdapter &adapter, + BluetoothDevice &remote_device) : device_(remote_device), adapter_(adapter) {} bool BluetoothPairing::InitiatePairing( diff --git a/internal/platform/implementation/linux/bluetooth_pairing.h b/internal/platform/implementation/linux/bluetooth_pairing.h index 157f095e..80fce60c 100644 --- a/internal/platform/implementation/linux/bluetooth_pairing.h +++ b/internal/platform/implementation/linux/bluetooth_pairing.h @@ -17,9 +17,8 @@ namespace nearby { namespace linux { class BluetoothPairing : public api::BluetoothPairing { public: - BluetoothPairing(const sdbus::ObjectPath &adapter_object_path, - BluetoothDevice &remote_device, BluetoothAdapter &adapter, - sdbus::IConnection &system_bus); + BluetoothPairing(BluetoothAdapter &adapter, + BluetoothDevice &remote_device); ~BluetoothPairing() override = default; bool InitiatePairing(api::BluetoothPairingCallback pairing_cb) override; @@ -36,7 +35,6 @@ private: BluetoothDevice &device_; BluetoothAdapter &adapter_; - std::unique_ptr bluez_adapter_proxy_; api::BluetoothPairingCallback pairing_cb_; }; } // namespace linux diff --git a/internal/platform/implementation/linux/bluez.cc b/internal/platform/implementation/linux/bluez.cc index 2fde4c17..b5c7c118 100644 --- a/internal/platform/implementation/linux/bluez.cc +++ b/internal/platform/implementation/linux/bluez.cc @@ -27,6 +27,10 @@ sdbus::ObjectPath profile_object_path(absl::string_view service_uuid) { return absl::Substitute("/com/github/google/nearby/profiles/$0", service_uuid); } +sdbus::ObjectPath adapter_object_path(absl::string_view name) { + return absl::Substitute("/org/bluez/$0", name); +} + } // namespace bluez } // namespace linux } // namespace nearby diff --git a/internal/platform/implementation/linux/bluez.h b/internal/platform/implementation/linux/bluez.h index 45471fea..dc7bb55d 100644 --- a/internal/platform/implementation/linux/bluez.h +++ b/internal/platform/implementation/linux/bluez.h @@ -34,6 +34,8 @@ device_object_path(const sdbus::ObjectPath &adapter_object_path, extern sdbus::ObjectPath profile_object_path(absl::string_view service_uuid); +extern sdbus::ObjectPath adapter_object_path(absl::string_view name); + } // namespace bluez } // namespace linux } // namespace nearby