#ifndef DEVICE_BLUETOOTH_FLOSS_FLOSS_MANAGER_CLIENT_H_
#define DEVICE_BLUETOOTH_FLOSS_FLOSS_MANAGER_CLIENT_H_
#include <memory>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "dbus/exported_object.h"
#include "dbus/object_manager.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/floss/exported_callback_manager.h"
#include "device/bluetooth/floss/floss_dbus_client.h"
#include "device/bluetooth/floss/floss_version.h"
namespace dbus {
class PropertySet;
}
namespace floss {
namespace internal {
struct AdapterWithEnabled {
int adapter;
bool enabled;
};
class DEVICE_BLUETOOTH_EXPORT FlossManagerClientCallbacks {
public:
FlossManagerClientCallbacks(const FlossManagerClientCallbacks&) = delete;
FlossManagerClientCallbacks& operator=(const FlossManagerClientCallbacks&) =
delete;
FlossManagerClientCallbacks() = default;
virtual ~FlossManagerClientCallbacks() = default;
virtual void OnHciDeviceChanged(int32_t adapter, bool present) = 0;
virtual void OnHciEnabledChanged(int32_t adapter, bool enabled) = 0;
virtual void OnDefaultAdapterChanged(int32_t adapter) = 0;
};
}
class DEVICE_BLUETOOTH_EXPORT FlossManagerClient
: public FlossDBusClient,
public internal::FlossManagerClientCallbacks,
public dbus::ObjectManager::Interface {
public:
class Observer : public base::CheckedObserver {
public:
Observer(const Observer&) = delete;
Observer& operator=(const Observer&) = delete;
Observer() = default;
~Observer() override = default;
virtual void ManagerPresent(bool present) {}
virtual void AdapterPresent(int adapter, bool present) {}
virtual void AdapterEnabledChanged(int adapter, bool enabled) {}
virtual void DefaultAdapterChanged(int previous, int adapter) {}
};
static std::unique_ptr<FlossManagerClient> Create();
FlossManagerClient(const FlossManagerClient&) = delete;
FlossManagerClient& operator=(const FlossManagerClient&) = delete;
FlossManagerClient();
~FlossManagerClient() override;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
virtual std::vector<int> GetAdapters() const;
virtual int GetDefaultAdapter() const;
virtual bool GetAdapterPresent(int adapter) const;
virtual bool GetAdapterEnabled(int adapter) const;
virtual void SetAdapterEnabled(int adapter,
bool enabled,
ResponseCallback<Void> callback);
virtual base::Version GetFlossApiVersion() const;
virtual void SetLLPrivacy(ResponseCallback<bool> callback, const bool enable);
void Init(dbus::Bus* bus,
const std::string& service_name,
const int adapter_index,
base::Version version,
base::OnceClosure on_ready) override;
bool IsInitialized() const { return init_; }
protected:
friend class FlossManagerClientTest;
void GetFlossEnabledWithTarget(bool target, int retry, int retry_wait_ms);
void SetFlossEnabled(bool enable,
int retry,
int retry_wait_ms,
std::optional<ResponseCallback<bool>> cb);
void DoGetFlossApiVersion();
bool IsCompatibleFlossApi();
void HandleGetDefaultAdapter(DBusResult<int32_t> response);
void HandleGetAvailableAdapters(
DBusResult<std::vector<internal::AdapterWithEnabled>> adapters);
void HandleGetAdapterEnabledAfterPresent(int32_t adapter,
DBusResult<bool> response);
void HandleRegisterCallback(DBusResult<Void> result);
void OnHciDeviceChanged(int32_t adapter, bool present) override;
void OnHciEnabledChanged(int32_t adapter, bool enabled) override;
void OnDefaultAdapterChanged(int32_t adapter) override;
void HandleSetFlossEnabled(bool target,
int retry,
int retry_wait_ms,
DBusResult<Void> response);
void HandleGetFlossEnabled(bool target,
int retry,
int retry_wait_ms,
DBusResult<bool> response);
void CompleteSetFlossEnabled(DBusResult<bool> ret);
void HandleGetFlossApiVersion(DBusResult<uint32_t> response);
void RegisterWithManager();
void RemoveManager();
dbus::PropertySet* CreateProperties(
dbus::ObjectProxy* object_proxy,
const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
void ObjectAdded(const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
void ObjectRemoved(const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
raw_ptr<dbus::Bus> bus_ = nullptr;
raw_ptr<dbus::ObjectManager> object_manager_ = nullptr;
bool manager_available_ = false;
int default_adapter_ = 0;
base::flat_map<int, bool> adapter_to_enabled_;
base::flat_set<int> adapter_present_pending_;
std::string service_name_;
base::ObserverList<Observer> observers_;
bool init_ = false;
private:
void OnSetAdapterEnabled(DBusResult<Void> response);
template <typename R, typename... Args>
void CallExperimentalMethod(ResponseCallback<R> callback,
const char* member,
Args... args) {
CallMethod(std::move(callback), bus_, service_name_, kExperimentalInterface,
dbus::ObjectPath(kManagerObject), member, args...);
}
static const char kExportedCallbacksPath[];
static const char kObjectManagerPath[];
static const int kSetFlossRetryCount;
static const int kSetFlossRetryDelayMs;
static const int kSetFlossEnabledDBusTimeoutMs;
std::unique_ptr<WeaklyOwnedResponseCallback<Void>> adapter_enabled_callback_;
std::unique_ptr<WeaklyOwnedResponseCallback<bool>>
set_floss_enabled_callback_;
template <typename R, typename... Args>
void CallManagerMethod(ResponseCallback<R> callback,
const char* member,
Args... args) {
CallMethod(std::move(callback), bus_, service_name_, kManagerInterface,
dbus::ObjectPath(kManagerObject), member, args...);
}
ExportedCallbackManager<FlossManagerClientCallbacks>
exported_callback_manager_{manager::kCallbackInterface};
base::OnceClosure on_ready_;
base::WeakPtrFactory<FlossManagerClient> weak_ptr_factory_{this};
};
}
#endif