blob: 9799fc84aae1aa8c80b25a4d429f3da552c9b5f0 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#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 dbus
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;
// Notification sent when the policy effect to a device changed.
virtual void DevicePolicyEffectChanged(
const FlossDeviceId& device_id,
const absl::optional<PolicyEffect>& effect) {}
// Notification sent when the service allowlist changed.
virtual void ServiceAllowlistChanged(
const std::vector<device::BluetoothUUID>& allowlist) {}
};
// Low-level interface to Floss's Admin API.
class DEVICE_BLUETOOTH_EXPORT FlossAdminClient : public FlossDBusClient {
friend class FlossAdminClientTest;
public:
// Error: No such adapter.
static const char kErrorUnknownAdapter[];
// Creates the instance.
static std::unique_ptr<FlossAdminClient> Create();
FlossAdminClient(const FlossAdminClient&) = delete;
FlossAdminClient& operator=(const FlossAdminClient&) = delete;
FlossAdminClient();
~FlossAdminClient() override;
// Manage observers.
void AddObserver(FlossAdminClientObserver* observer);
void RemoveObserver(FlossAdminClientObserver* observer);
// Initialize the Admin client.
void Init(dbus::Bus* bus,
const std::string& service_name,
const int adapter_index,
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);
protected:
// Handle callback |OnDevicePolicyEffectChanged| on exported object path.
void OnDevicePolicyEffectChanged(const FlossDeviceId& device_id,
const absl::optional<PolicyEffect>& effect);
// Handle callback |OnServiceAllowlistChanged| on exported object path
void OnServiceAllowlistChanged(
const std::vector<std::vector<uint8_t>>& allowlist);
// Handle the response of GetAllowedServices.
void HandleGetAllowedServices(
ResponseCallback<std::vector<device::BluetoothUUID>> callback,
DBusResult<std::vector<std::vector<uint8_t>>> result);
// Managed by FlossDBusManager - we keep local pointer to access object proxy.
raw_ptr<dbus::Bus> bus_ = nullptr;
// Admin managed by this client.
dbus::ObjectPath admin_path_;
// Service which implements the admin interface.
std::string service_name_;
// List of observers interested in event notifications from this client.
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...);
}
// Object path for exported callbacks registered against adapter interface.
static const char kExportedCallbacksPath[];
// Exported callbacks for interacting with daemon.
ExportedCallbackManager<FlossAdminClient> exported_callback_manager_{
admin::kCallbackInterface};
// Callback ID used for callbacks registered to this client.
absl::optional<uint32_t> callback_id_;
// Signal when the client is ready to be used.
base::OnceClosure on_ready_;
base::WeakPtrFactory<FlossAdminClient> weak_ptr_factory_{this};
};
} // namespace floss
#endif // DEVICE_BLUETOOTH_FLOSS_FLOSS_ADMIN_CLIENT_H_