1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
// 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 std::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::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);
protected:
// Handle callback |OnDevicePolicyEffectChanged| on exported object path.
void OnDevicePolicyEffectChanged(const FlossDeviceId& device_id,
const std::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.
std::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_
|