blob: 44c6323c7e7a5cfcae095bcf45bbdc5034214cea [file] [log] [blame]
// 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