30 std::lock_guard lock(mutex_);
31 for (
auto& [h,
buddy] : trackedBuddies_) {
32 if (dht_ && dht_->isRunning()) {
33 dht_->cancelListen(h, std::move(
buddy.listenToken));
45 std::lock_guard lock(mutex_);
46 auto it = trackedBuddies_.find(h);
47 if (
it == trackedBuddies_.end()) {
48 it = trackedBuddies_.emplace(h, TrackedBuddy {h}).
first;
51 it->second.refCount++;
52 if (
it->second.refCount == 1) {
53 trackPresence(h,
it->second);
64 std::lock_guard lock(mutex_);
65 auto it = trackedBuddies_.find(h);
66 if (
it != trackedBuddies_.end()) {
67 it->second.refCount--;
68 if (
it->second.refCount <= 0) {
69 if (dht_ && dht_->isRunning()) {
70 dht_->cancelListen(h, std::move(
it->second.listenToken));
72 trackedBuddies_.erase(
it);
83 std::lock_guard lock(mutex_);
84 auto it = trackedBuddies_.find(h);
85 return it != trackedBuddies_.end() && !
it->second.devices.empty();
88std::map<std::string, bool>
91 std::lock_guard lock(mutex_);
93 for (
const auto& [h,
buddy] : trackedBuddies_) {
102 dht::InfoHash h(uri);
105 std::lock_guard lock(mutex_);
106 auto it = trackedBuddies_.find(h);
107 if (
it == trackedBuddies_.end())
109 return {
it->second.devices.begin(),
it->second.devices.end()};
115 std::lock_guard lock(listenersMutex_);
116 auto id = nextListenerId_++;
117 listeners_.emplace(
id, std::move(
cb));
124 std::lock_guard lock(listenersMutex_);
125 listeners_.erase(token);
131 std::lock_guard lock(listenersMutex_);
132 auto id = nextListenerId_++;
133 deviceListeners_.emplace(
id, std::move(
cb));
140 std::lock_guard lock(listenersMutex_);
141 deviceListeners_.erase(token);
147 std::lock_guard lock(mutex_);
148 for (
auto& [h,
buddy] : trackedBuddies_) {
149 buddy.listenToken = {};
150 buddy.devices.clear();
151 trackPresence(h,
buddy);
156PresenceManager::trackPresence(
const dht::InfoHash& h, TrackedBuddy&
buddy)
158 if (!dht_ || !dht_->isRunning())
161 if (
buddy.listenToken.valid()) {
162 JAMI_ERROR(
"PresenceManager: Already tracking presence for {}", h.toString());
166 buddy.listenToken = dht_->listen<DeviceAnnouncement>(h, [
this, h](DeviceAnnouncement&&
dev,
bool expired) {
168 JAMI_WARNING(
"PresenceManager: Received DeviceAnnouncement without public key for {}", h.toString());
172 auto deviceId =
dev.pk->getLongId();
175 std::lock_guard lock(mutex_);
176 auto it = trackedBuddies_.find(h);
177 if (
it == trackedBuddies_.end())
182 it->second.devices.erase(deviceId);
184 it->second.devices.insert(deviceId);
186 isConnected = !
it->second.devices.empty();
189 notifyDeviceListeners(h.toString(), deviceId,
deviceOnline);
192 notifyListeners(h.toString(), isConnected);
199PresenceManager::notifyListeners(
const std::string& uri,
bool online)
201 std::vector<PresenceCallback>
cbs;
203 std::lock_guard lock(listenersMutex_);
204 cbs.reserve(listeners_.size());
205 for (
const auto& [
id,
cb] : listeners_) {
206 cbs.emplace_back(
cb);
209 for (
const auto&
cb :
cbs) {
215PresenceManager::notifyDeviceListeners(
const std::string& uri,
const dht::PkId& deviceId,
bool online)
217 std::vector<DevicePresenceCallback>
cbs;
219 std::lock_guard lock(listenersMutex_);
220 cbs.reserve(deviceListeners_.size());
221 for (
const auto& [
id,
cb] : deviceListeners_) {
222 cbs.emplace_back(
cb);
225 for (
const auto&
cb :
cbs) {
std::function< void(const std::string &uri, const dht::PkId &deviceId, bool online)> DevicePresenceCallback
PresenceManager(const std::shared_ptr< dht::DhtRunner > &dht)
uint64_t addListener(PresenceCallback cb)
Add a listener for presence changes.
void refresh()
Refresh all tracked buddies.
bool isOnline(const std::string &uri) const
Check if a buddy is currently online.
std::map< std::string, bool > getTrackedBuddyPresence() const
Get the presence status of all tracked buddies.
void removeDeviceListener(uint64_t token)
Remove a listener using the token returned by addDeviceListener.
uint64_t addDeviceListener(DevicePresenceCallback cb)
Add a listener for device presence changes.
std::function< void(const std::string &uri, bool online)> PresenceCallback
void trackBuddy(const std::string &uri)
Start tracking a buddy.
void removeListener(uint64_t token)
Remove a listener using the token returned by addListener.
void untrackBuddy(const std::string &uri)
Stop tracking a buddy.
std::vector< dht::PkId > getDevices(const std::string &uri) const
Get the list of devices for a tracked buddy.
#define JAMI_ERROR(formatstr,...)
#define JAMI_WARNING(formatstr,...)
void emitSignal(Args... args)