blob: dfff8633d5a6422aed87bfe68fdc03078df3aa03 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/bluetooth/dbus/bluetooth_debug_manager_client.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_manager.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace bluez {
// TODO(apusaka): move these consts to system_api/service_constants.h
namespace {
const char kBluetoothDebugObjectPath[] = "/org/chromium/Bluetooth";
const uint8_t kMinBluezLevel = 0;
const uint8_t kMinKernelLevel = 0;
const uint8_t kMaxBluezLevel = 2;
const uint8_t kMaxKernelLevel = 1;
} // namespace
const char BluetoothDebugManagerClient::kNoResponseError[] =
"org.chromium.Error.NoResponse";
const char BluetoothDebugManagerClient::kInvalidArgumentError[] =
"org.chromium.Error.InvalidArgument";
// The BluetoothDebugManagerClient implementation used in production.
class BluetoothDebugManagerClientImpl : public BluetoothDebugManagerClient,
public dbus::ObjectManager::Interface {
public:
BluetoothDebugManagerClientImpl() = default;
BluetoothDebugManagerClientImpl(const BluetoothDebugManagerClientImpl&) =
delete;
BluetoothDebugManagerClientImpl& operator=(
const BluetoothDebugManagerClientImpl&) = delete;
~BluetoothDebugManagerClientImpl() override = default;
// BluetoothDebugManagerClient override.
void SetLLPrivacy(const bool enable,
base::OnceClosure callback,
ErrorCallback error_callback) override {
constexpr char kLLPrivacy[] = "SetLLPrivacy";
dbus::MethodCall method_call(bluetooth_debug::kBluetoothDebugInterface,
kLLPrivacy);
dbus::MessageWriter writer(&method_call);
writer.AppendBool(enable);
object_proxy_->CallMethodWithErrorResponse(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::BindOnce(&BluetoothDebugManagerClientImpl::OnMethodResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
std::move(error_callback)));
}
void SetBluetoothQualityReport(const bool enable,
base::OnceClosure callback,
ErrorCallback error_callback) override {
dbus::MethodCall method_call(bluetooth_debug::kBluetoothDebugInterface,
bluetooth_debug::kSetBluetoothQualityReport);
dbus::MessageWriter writer(&method_call);
// Convert enable to uint8_t as the dbus method takes a byte.
writer.AppendByte((uint8_t)enable);
object_proxy_->CallMethodWithErrorResponse(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::BindOnce(&BluetoothDebugManagerClientImpl::OnMethodResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
std::move(error_callback)));
}
// BluetoothDebugManagerClient override.
void SetLogLevels(const uint8_t bluez_level,
const uint8_t kernel_level,
base::OnceClosure callback,
ErrorCallback error_callback) override {
if (kMinBluezLevel > bluez_level || kMaxBluezLevel < bluez_level) {
std::move(error_callback)
.Run(kInvalidArgumentError, "bluez_level is out of range.");
return;
}
if (kMinKernelLevel > kernel_level || kMaxKernelLevel < kernel_level) {
std::move(error_callback)
.Run(kInvalidArgumentError, "kernel_level is out of range.");
return;
}
dbus::MethodCall method_call(bluetooth_debug::kBluetoothDebugInterface,
bluetooth_debug::kSetLevels);
dbus::MessageWriter writer(&method_call);
writer.AppendByte(bluez_level);
writer.AppendByte(kernel_level);
object_proxy_->CallMethodWithErrorResponse(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::BindOnce(&BluetoothDebugManagerClientImpl::OnMethodResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
std::move(error_callback)));
}
protected:
void Init(dbus::Bus* bus,
const std::string& bluetooth_service_name) override {
DCHECK(bus);
object_proxy_ = bus->GetObjectProxy(
bluetooth_service_name, dbus::ObjectPath(kBluetoothDebugObjectPath));
object_manager_ = bus->GetObjectManager(
bluetooth_service_name,
dbus::ObjectPath(
bluetooth_object_manager::kBluetoothObjectManagerServicePath));
object_manager_->RegisterInterface(
bluetooth_debug::kBluetoothDebugInterface, this);
}
private:
// dbus::ObjectManager::Interface override.
dbus::PropertySet* CreateProperties(
dbus::ObjectProxy* object_proxy,
const dbus::ObjectPath& object_path,
const std::string& interface_name) override {
return new dbus::PropertySet(object_proxy, interface_name,
base::DoNothing());
}
void OnMethodResponse(base::OnceClosure callback,
ErrorCallback error_callback,
dbus::Response* response,
dbus::ErrorResponse* error_response) {
if (!response) {
std::string error_name;
std::string error_message;
if (error_response) {
dbus::MessageReader reader(error_response);
error_name = error_response->GetErrorName();
reader.PopString(&error_message);
} else {
error_name = kNoResponseError;
}
std::move(error_callback).Run(error_name, error_message);
return;
}
std::move(callback).Run();
}
raw_ptr<dbus::ObjectProxy> object_proxy_;
raw_ptr<dbus::ObjectManager> object_manager_;
base::WeakPtrFactory<BluetoothDebugManagerClientImpl> weak_ptr_factory_{this};
};
BluetoothDebugManagerClient::BluetoothDebugManagerClient() = default;
BluetoothDebugManagerClient::~BluetoothDebugManagerClient() = default;
BluetoothDebugManagerClient* BluetoothDebugManagerClient::Create() {
return new BluetoothDebugManagerClientImpl();
}
} // namespace bluez