From d2f3be5ad9cbdef4c8339ebaa23537573b18809f Mon Sep 17 00:00:00 2001
From: Olivier Dion <olivier.dion@savoirfairelinux.com>
Date: Fri, 28 May 2021 10:16:28 -0400
Subject: [PATCH] jamidht: Add device announced volatile properties

Change-Id: Id1c0920b861704249c8beeb0c0c205fc770d7bb5
---
 src/dring/account_const.h               |  1 +
 src/jamidht/account_manager.cpp         | 16 ++++++++++++++--
 src/jamidht/account_manager.h           |  3 ++-
 src/jamidht/archive_account_manager.cpp |  4 ++--
 src/jamidht/archive_account_manager.h   |  2 +-
 src/jamidht/jamiaccount.cpp             |  9 ++++++++-
 src/jamidht/jamiaccount.h               |  2 ++
 7 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/src/dring/account_const.h b/src/dring/account_const.h
index fd065e7dac..e835b8a866 100644
--- a/src/dring/account_const.h
+++ b/src/dring/account_const.h
@@ -74,6 +74,7 @@ enum class MessageStates : int {
 namespace VolatileProperties {
 
 constexpr static const char ACTIVE[] = "Account.active";
+constexpr static const char DEVICE_ANNOUNCED[] = "Account.deviceAnnounced";
 constexpr static const char REGISTERED_NAME[] = "Account.registeredName";
 
 // Volatile parameters
diff --git a/src/jamidht/account_manager.cpp b/src/jamidht/account_manager.cpp
index dfbc3a9059..0e00ae6668 100644
--- a/src/jamidht/account_manager.cpp
+++ b/src/jamidht/account_manager.cpp
@@ -190,13 +190,25 @@ AccountManager::useIdentity(const dht::crypto::Identity& identity,
 }
 
 void
-AccountManager::startSync(const OnNewDeviceCb& cb)
+AccountManager::startSync(const OnNewDeviceCb& cb, const OnDeviceAnnouncedCb& dcb)
 {
     // Put device announcement
     if (info_->announce) {
         auto h = dht::InfoHash(info_->accountId);
         JAMI_DBG("announcing device at %s", h.toString().c_str());
-        dht_->put(h, info_->announce, dht::DoneCallback {}, {}, true);
+        dht_->put(
+            h,
+            info_->announce,
+            [dcb = std::move(dcb), h](bool ok) {
+                if (ok)
+                    JAMI_DBG("device announced at %s", h.toString().c_str());
+                // We do not care about the status, it's a permanent put, if this fail,
+                // this means the DHT is disconnected but the put will be retried when connected.
+                if (dcb)
+                    dcb();
+            },
+            {},
+            true);
         for (const auto& crl : info_->identity.second->issuer->getRevocationLists())
             dht_->put(h, crl, dht::DoneCallback {}, {}, true);
         dht_->listen<DeviceAnnouncement>(h, [this, cb = std::move(cb)](DeviceAnnouncement&& dev) {
diff --git a/src/jamidht/account_manager.h b/src/jamidht/account_manager.h
index 6d9bb8df71..2adcf39f9a 100644
--- a/src/jamidht/account_manager.h
+++ b/src/jamidht/account_manager.h
@@ -77,6 +77,7 @@ public:
     using clock = std::chrono::system_clock;
     using time_point = clock::time_point;
     using OnNewDeviceCb = std::function<void(const std::shared_ptr<dht::crypto::Certificate>&)>;
+    using OnDeviceAnnouncedCb = std::function<void()>;
 
     AccountManager(const std::string& path, OnAsync&& onAsync, const std::string& nameServer)
         : path_(path)
@@ -137,7 +138,7 @@ public:
 
     void setDht(const std::shared_ptr<dht::DhtRunner>& dht) { dht_ = dht; }
 
-    virtual void startSync(const OnNewDeviceCb& cb);
+    virtual void startSync(const OnNewDeviceCb& cb, const OnDeviceAnnouncedCb& dcb);
 
     const AccountInfo* getInfo() const { return info_.get(); }
 
diff --git a/src/jamidht/archive_account_manager.cpp b/src/jamidht/archive_account_manager.cpp
index 66c07f4170..661df63474 100644
--- a/src/jamidht/archive_account_manager.cpp
+++ b/src/jamidht/archive_account_manager.cpp
@@ -451,9 +451,9 @@ ArchiveAccountManager::syncDevices()
 }
 
 void
-ArchiveAccountManager::startSync(const OnNewDeviceCb& cb)
+ArchiveAccountManager::startSync(const OnNewDeviceCb& cb, const OnDeviceAnnouncedCb& dcb)
 {
-    AccountManager::startSync(std::move(cb));
+    AccountManager::startSync(std::move(cb), std::move(dcb));
 
     dht_->listen<DeviceSync>(dht::InfoHash::get("inbox:" + info_->deviceId), [this](DeviceSync&& sync) {
         // Received device sync data.
diff --git a/src/jamidht/archive_account_manager.h b/src/jamidht/archive_account_manager.h
index e10c357fa5..85145cc5bc 100644
--- a/src/jamidht/archive_account_manager.h
+++ b/src/jamidht/archive_account_manager.h
@@ -49,7 +49,7 @@ public:
                             AuthFailureCallback onFailure,
                             OnChangeCallback onChange) override;
 
-    void startSync(const OnNewDeviceCb&) override;
+    void startSync(const OnNewDeviceCb&, const OnDeviceAnnouncedCb& dcb = {}) override;
 
     bool changePassword(const std::string& password_old, const std::string& password_new) override;
 
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 740e67f317..9afee70c80 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -1535,6 +1535,9 @@ JamiAccount::getVolatileAccountDetails() const
     if (not registeredName_.empty())
         a.emplace(DRing::Account::VolatileProperties::REGISTERED_NAME, registeredName_);
 #endif
+    a.emplace(DRing::Account::VolatileProperties::DEVICE_ANNOUNCED,
+              deviceAnnounced_ ? TRUE_STR : FALSE_STR);
+
     return a;
 }
 
@@ -2142,7 +2145,11 @@ JamiAccount::doRegister_()
         context.identityAnnouncedCb = [this](bool ok) {
             if (!ok)
                 return;
-            accountManager_->startSync({});
+            accountManager_->startSync({}, [this] {
+                deviceAnnounced_ = true;
+                emitSignal<DRing::ConfigurationSignal::VolatileDetailsChanged>(
+                    accountID_, getVolatileAccountDetails());
+            });
             /*[this](const std::shared_ptr<dht::crypto::Certificate>& crt) {
                 if (!crt)
                     return;
diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h
index 1ecf86c239..e6ccbe0734 100644
--- a/src/jamidht/jamiaccount.h
+++ b/src/jamidht/jamiaccount.h
@@ -980,6 +980,8 @@ private:
      * @return the conversation id if found else empty
      */
     std::string getOneToOneConversation(const std::string& uri) const;
+
+    std::atomic_bool deviceAnnounced_ {false};
 };
 
 static inline std::ostream&
-- 
GitLab