| // Copyright 2019 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "diagnostics/common/system/bluetooth_client_impl.h" |
| |
| #include <base/bind.h> |
| #include <base/logging.h> |
| #include <dbus/bluetooth/dbus-constants.h> |
| |
| namespace diagnostics { |
| |
| namespace { |
| |
| bool AreAdapterPropertiesValid( |
| const BluetoothClient::AdapterProperties& adapter_properties) { |
| return adapter_properties.name.is_valid() && |
| adapter_properties.address.is_valid() && |
| adapter_properties.powered.is_valid(); |
| } |
| |
| bool AreDevicePropertiesValid( |
| const BluetoothClient::DeviceProperties& device_properties) { |
| return device_properties.name.is_valid() && |
| device_properties.address.is_valid() && |
| device_properties.connected.is_valid(); |
| } |
| |
| } // namespace |
| |
| BluetoothClientImpl::BluetoothClientImpl(const scoped_refptr<dbus::Bus>& bus) |
| : object_manager_(bus->GetObjectManager( |
| bluez_object_manager::kBluezObjectManagerServiceName, |
| dbus::ObjectPath( |
| bluez_object_manager::kBluezObjectManagerServicePath))), |
| weak_ptr_factory_(this) { |
| DCHECK(object_manager_); |
| object_manager_->RegisterInterface( |
| bluetooth_adapter::kBluetoothAdapterInterface, this); |
| object_manager_->RegisterInterface( |
| bluetooth_device::kBluetoothDeviceInterface, this); |
| } |
| |
| BluetoothClientImpl::~BluetoothClientImpl() { |
| object_manager_->UnregisterInterface( |
| bluetooth_adapter::kBluetoothAdapterInterface); |
| object_manager_->UnregisterInterface( |
| bluetooth_device::kBluetoothDeviceInterface); |
| } |
| |
| std::vector<dbus::ObjectPath> BluetoothClientImpl::GetAdapters() { |
| VLOG(3) << __func__; |
| |
| return object_manager_->GetObjectsWithInterface( |
| bluetooth_adapter::kBluetoothAdapterInterface); |
| } |
| |
| std::vector<dbus::ObjectPath> BluetoothClientImpl::GetDevices() { |
| VLOG(3) << __func__; |
| |
| return object_manager_->GetObjectsWithInterface( |
| bluetooth_device::kBluetoothDeviceInterface); |
| } |
| |
| const BluetoothClient::AdapterProperties* |
| BluetoothClientImpl::GetAdapterProperties( |
| const dbus::ObjectPath& adapter_path) { |
| VLOG(3) << __func__ << " " << adapter_path.value(); |
| |
| auto adapter_properties = |
| static_cast<AdapterProperties*>(object_manager_->GetProperties( |
| adapter_path, bluetooth_adapter::kBluetoothAdapterInterface)); |
| if (!adapter_properties || !AreAdapterPropertiesValid(*adapter_properties)) { |
| VLOG(3) << "No valid properties found for " << adapter_path.value(); |
| return nullptr; |
| } |
| |
| return adapter_properties; |
| } |
| |
| const BluetoothClient::DeviceProperties* |
| BluetoothClientImpl::GetDeviceProperties(const dbus::ObjectPath& device_path) { |
| VLOG(3) << __func__ << " " << device_path.value(); |
| |
| auto device_properties = |
| static_cast<DeviceProperties*>(object_manager_->GetProperties( |
| device_path, bluetooth_device::kBluetoothDeviceInterface)); |
| if (!device_properties || !AreDevicePropertiesValid(*device_properties)) { |
| VLOG(3) << "No valid properties found for " << device_path.value(); |
| return nullptr; |
| } |
| |
| return device_properties; |
| } |
| |
| dbus::PropertySet* BluetoothClientImpl::CreateProperties( |
| dbus::ObjectProxy* object_proxy, |
| const dbus::ObjectPath& object_path, |
| const std::string& interface_name) { |
| VLOG(3) << __func__ << " " << object_path.value() << " " << interface_name; |
| |
| auto callback = |
| base::Bind(&BluetoothClientImpl::PropertyChanged, |
| weak_ptr_factory_.GetWeakPtr(), object_path, interface_name); |
| if (interface_name == bluetooth_adapter::kBluetoothAdapterInterface) { |
| return new AdapterProperties(object_proxy, callback); |
| } |
| if (interface_name == bluetooth_device::kBluetoothDeviceInterface) { |
| return new DeviceProperties(object_proxy, callback); |
| } |
| NOTREACHED() << "Invalid interface name: " << interface_name; |
| return nullptr; |
| } |
| |
| void BluetoothClientImpl::ObjectAdded(const dbus::ObjectPath& object_path, |
| const std::string& interface_name) { |
| VLOG(3) << __func__ << " " << object_path.value() << " " << interface_name; |
| |
| dbus::PropertySet* properties = |
| object_manager_->GetProperties(object_path, interface_name); |
| if (!properties) { |
| VLOG(3) << "Not found properties for " << object_path.value(); |
| return; |
| } |
| |
| if (interface_name == bluetooth_adapter::kBluetoothAdapterInterface) { |
| auto adapter_properties = static_cast<AdapterProperties*>(properties); |
| if (!AreAdapterPropertiesValid(*adapter_properties)) { |
| return; |
| } |
| for (auto& observer : observers_) |
| observer.AdapterAdded(object_path, *adapter_properties); |
| return; |
| } |
| if (interface_name == bluetooth_device::kBluetoothDeviceInterface) { |
| auto device_properties = static_cast<DeviceProperties*>(properties); |
| if (!AreDevicePropertiesValid(*device_properties)) { |
| return; |
| } |
| for (auto& observer : observers_) |
| observer.DeviceAdded(object_path, *device_properties); |
| return; |
| } |
| NOTREACHED() << "Invalid interface name: " << interface_name; |
| } |
| |
| void BluetoothClientImpl::ObjectRemoved(const dbus::ObjectPath& object_path, |
| const std::string& interface_name) { |
| VLOG(3) << __func__ << " " << object_path.value() << " " << interface_name; |
| |
| if (interface_name == bluetooth_adapter::kBluetoothAdapterInterface) { |
| for (auto& observer : observers_) |
| observer.AdapterRemoved(object_path); |
| return; |
| } |
| if (interface_name == bluetooth_device::kBluetoothDeviceInterface) { |
| for (auto& observer : observers_) |
| observer.DeviceRemoved(object_path); |
| return; |
| } |
| NOTREACHED() << "Invalid interface name: " << interface_name; |
| } |
| |
| void BluetoothClientImpl::PropertyChanged(const dbus::ObjectPath& object_path, |
| const std::string& interface_name, |
| const std::string& property_name) { |
| VLOG(3) << __func__ << " " << object_path.value() << " " << interface_name |
| << " " << property_name; |
| |
| dbus::PropertySet* properties = |
| object_manager_->GetProperties(object_path, interface_name); |
| if (!properties) { |
| VLOG(3) << "Not found properties for " << object_path.value(); |
| return; |
| } |
| |
| if (interface_name == bluetooth_adapter::kBluetoothAdapterInterface) { |
| auto adapter_properties = static_cast<AdapterProperties*>(properties); |
| if (!AreAdapterPropertiesValid(*adapter_properties)) { |
| return; |
| } |
| for (auto& observer : observers_) |
| observer.AdapterPropertyChanged(object_path, *adapter_properties); |
| return; |
| } |
| if (interface_name == bluetooth_device::kBluetoothDeviceInterface) { |
| auto device_properties = static_cast<DeviceProperties*>(properties); |
| if (!AreDevicePropertiesValid(*device_properties)) { |
| return; |
| } |
| for (auto& observer : observers_) |
| observer.DevicePropertyChanged(object_path, *device_properties); |
| return; |
| } |
| NOTREACHED() << "Invalid interface name: " << interface_name; |
| } |
| |
| } // namespace diagnostics |