#ifndef DEVICE_BLUETOOTH_FLOSS_FLOSS_ADMIN_CLIENT_H_
#define DEVICE_BLUETOOTH_FLOSS_FLOSS_ADMIN_CLIENT_H_
#include <queue>
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "dbus/exported_object.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/floss/exported_callback_manager.h"
#include "device/bluetooth/floss/floss_dbus_client.h"
namespace dbus {
class ObjectPath;
}
namespace floss {
const char kAdminCallbackInterfaceName[] =
"org.chromium.bluetooth.BluetoothAdmin";
struct DEVICE_BLUETOOTH_EXPORT PolicyEffect {
std::vector<std::vector<uint8_t>> service_blocked;
bool affected;
PolicyEffect();
PolicyEffect(const PolicyEffect&);
~PolicyEffect();
};
class FlossAdminClientObserver : public base::CheckedObserver {
public:
FlossAdminClientObserver(const FlossAdminClientObserver&) = delete;
FlossAdminClientObserver& operator=(const FlossAdminClientObserver&) = delete;
FlossAdminClientObserver() = default;
~FlossAdminClientObserver() override = default;
virtual void DevicePolicyEffectChanged(
const FlossDeviceId& device_id,
const std::optional<PolicyEffect>& effect) {}
virtual void ServiceAllowlistChanged(
const std::vector<device::BluetoothUUID>& allowlist) {}
};
class DEVICE_BLUETOOTH_EXPORT FlossAdminClient : public FlossDBusClient {
friend class FlossAdminClientTest;
public:
static const char kErrorUnknownAdapter[];
static std::unique_ptr<FlossAdminClient> Create();
FlossAdminClient(const FlossAdminClient&) = delete;
FlossAdminClient& operator=(const FlossAdminClient&) = delete;
FlossAdminClient();
~FlossAdminClient() override;
void AddObserver(FlossAdminClientObserver* observer);
void RemoveObserver(FlossAdminClientObserver* observer);
void Init(dbus::Bus* bus,
const std::string& service_name,
const int adapter_index,
base::Version version,
base::OnceClosure on_ready) override;
virtual void SetAllowedServices(
ResponseCallback<Void> callback,
const std::vector<device::BluetoothUUID>& UUIDs);
virtual void GetAllowedServices(
ResponseCallback<std::vector<device::BluetoothUUID>> callback);
virtual void GetDevicePolicyEffect(ResponseCallback<PolicyEffect> callback,
FlossDeviceId device);
virtual void SetSimpleSecurePairingEnabled(ResponseCallback<Void> callback,
const bool enable);
protected:
void OnDevicePolicyEffectChanged(const FlossDeviceId& device_id,
const std::optional<PolicyEffect>& effect);
void OnServiceAllowlistChanged(
const std::vector<std::vector<uint8_t>>& allowlist);
void HandleGetAllowedServices(
ResponseCallback<std::vector<device::BluetoothUUID>> callback,
DBusResult<std::vector<std::vector<uint8_t>>> result);
raw_ptr<dbus::Bus> bus_ = nullptr;
dbus::ObjectPath admin_path_;
std::string service_name_;
base::ObserverList<FlossAdminClientObserver> observers_;
private:
bool IsClientRegistered();
std::queue<base::OnceClosure> initialized_callbacks_;
bool client_registered_ = false;
void OnMethodsExported();
void HandleCallbackRegistered(DBusResult<uint32_t> result);
void HandleCallbackUnregistered(DBusResult<bool> result);
template <typename R, typename... Args>
void CallAdminMethod(ResponseCallback<R> callback,
const char* member,
Args... args) {
CallMethod(std::move(callback), bus_, service_name_, kAdminInterface,
admin_path_, member, args...);
}
static const char kExportedCallbacksPath[];
ExportedCallbackManager<FlossAdminClient> exported_callback_manager_{
admin::kCallbackInterface};
std::optional<uint32_t> callback_id_;
base::OnceClosure on_ready_;
base::WeakPtrFactory<FlossAdminClient> weak_ptr_factory_{this};
};
}
#endif