blob: e3b0813cbf8a1c6886226e90a0453734c9e90350 [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/dbus/bluetooth_bluez_proxy.h"
#include <memory>
#include <string>
#include <base/time/time.h>
#include <chromeos/dbus/bluetooth/dbus-constants.h>
#include <dbus/object_path.h>
#include "shill/event_dispatcher.h"
#include "shill/logging.h"
#include "shill/scope_logger.h"
namespace shill {
namespace Logging {
static auto kModuleLogScope = ScopeLogger::kBluetooth;
} // namespace Logging
namespace {
constexpr char kBlueZObjectPath[] = "/org/bluez/hci0";
constexpr base::TimeDelta kDBusInitializationDelay = base::Seconds(1);
} // namespace
BluetoothBlueZProxy::BluetoothBlueZProxy(const scoped_refptr<dbus::Bus>& bus,
EventDispatcher* dispatcher)
: init_complete_(false),
dispatcher_(dispatcher),
bluez_proxy_(new org::bluez::Adapter1Proxy(
bus,
bluetooth_adapter::kBluetoothAdapterServiceName,
dbus::ObjectPath(kBlueZObjectPath))) {
// One time callback when service becomes available.
bluez_proxy_->GetObjectProxy()->WaitForServiceToBeAvailable(base::BindOnce(
&BluetoothBlueZProxy::OnServiceAvailable, weak_factory_.GetWeakPtr()));
}
bool BluetoothBlueZProxy::GetAdapterPowered(bool* powered) const {
if (!init_complete_) {
LOG(ERROR) << __func__ << ": BT BlueZ adapter is not ready";
return false;
}
if (!bluez_proxy_->GetProperties()->GetAndBlock(
&bluez_proxy_->GetProperties()->powered)) {
LOG(ERROR) << "Failed to query BT 'Powered' property";
return false;
}
if (!bluez_proxy_->is_powered_valid()) {
LOG(ERROR) << "Invalid BT 'Powered' property";
return false;
}
*powered = bluez_proxy_->powered();
SLOG(3) << __func__ << ": " << bluez_proxy_->GetObjectPath().value()
<< ": BlueZ BT adapter is "
<< (bluez_proxy_->powered() ? "enabled" : "disabled");
return true;
}
void BluetoothBlueZProxy::CompleteInitialization() {
bluez_proxy_->InitializeProperties(base::BindRepeating(
&BluetoothBlueZProxy::OnPropertyChanged, weak_factory_.GetWeakPtr()));
init_complete_ = true;
LOG(INFO) << "Completed initialization of BT BlueZ proxy";
}
void BluetoothBlueZProxy::OnServiceAvailable(bool /* available */) {
LOG(INFO) << __func__ << ": BT BlueZ service is available";
// D-Bus race condition: the service reports that it's available before all
// the methods have been registered. Wait a little bit before querying.
// TODO(b/263432564): remove the delay once the race condition has been fixed.
dispatcher_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&BluetoothBlueZProxy::CompleteInitialization,
weak_factory_.GetWeakPtr()),
kDBusInitializationDelay);
}
void BluetoothBlueZProxy::OnPropertyChanged(
org::bluez::Adapter1ProxyInterface* /* proxy_interface */,
const std::string& property_name) {
SLOG(3) << __func__ << ": " << bluez_proxy_->GetObjectPath().value()
<< ": Property '" << property_name << "' changed";
}
} // namespace shill