diff --git a/map/framework.cpp b/map/framework.cpp index 2d9e9defa..3f87455de 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -2589,6 +2589,11 @@ void Framework::SaveTrafficEnabled(bool trafficEnabled) settings::Set(kTrafficEnabledKey, trafficEnabled); } +void Framework::SetTrafficHttpEnabled(bool enabled) +{ + m_trafficManager.SetHttpTraffSource(enabled, LoadTrafficHttpUrl()); +} + bool Framework::LoadTrafficHttpEnabled() { bool enabled; @@ -2602,6 +2607,11 @@ void Framework::SaveTrafficHttpEnabled(bool trafficHttpEnabled) settings::Set(kTrafficHttpEnabledKey, trafficHttpEnabled); } +void Framework::SetTrafficHttpUrl(std::string url) +{ + m_trafficManager.SetHttpTraffSource(LoadTrafficHttpEnabled(), url); +} + std::string Framework::LoadTrafficHttpUrl() { std::string url; diff --git a/map/framework.hpp b/map/framework.hpp index 96402b2cc..c70662dee 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -740,9 +740,11 @@ public: bool LoadTrafficEnabled(); void SaveTrafficEnabled(bool trafficEnabled); + void SetTrafficHttpEnabled(bool enabled); bool LoadTrafficHttpEnabled(); void SaveTrafficHttpEnabled(bool trafficHttpEnabled); + void SetTrafficHttpUrl(std::string url); std::string LoadTrafficHttpUrl(); void SaveTrafficHttpUrl(std::string trafficHttpUrl); diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 3d8fbc920..1a0173890 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -923,6 +923,27 @@ bool TrafficManager::IsEnabled() const return m_state != TrafficState::Disabled; } +void TrafficManager::SetHttpTraffSource(bool enabled, std::string url) +{ + if (IsTestMode()) + return; + + { + std::lock_guard lock(m_trafficSourceMutex); + + for (auto it = m_trafficSources.begin(); it != m_trafficSources.end(); ) + if (traffxml::HttpTraffSource* httpSource = dynamic_cast(it->get())) + { + httpSource->Close(); + m_trafficSources.erase(it); + } + else + ++it; + } + if (enabled) + traffxml::HttpTraffSource::Create(*this, url); +} + bool TrafficManager::IsInvalidState() const { return m_state == TrafficState::NetworkError; diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index db8fdad27..7b4fbe08e 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -173,6 +173,23 @@ public: */ bool IsEnabled() const; + /** + * @brief Sets the enabled state and URL for the `HttpTraffSource`. + * + * If the traffic manager is in test mode, this function is a no-op. + * + * Otherwise this function is expected to be called only if the enabled state and/or URL have + * actually changed. Setting both to the current state will remove the current source and create + * a new one with identical settings. + * + * This function currently assumes that there is never more than one `HttpTraffSource` configured + * at the same time. + * + * @param enabled Whether the HTTP TraFF source is enabled. + * @param url The URL for the TraFF API. + */ + void SetHttpTraffSource(bool enabled, std::string url); + /** * @brief Starts the traffic manager. * diff --git a/traffxml/traff_source.cpp b/traffxml/traff_source.cpp index de829fca8..2724d8136 100644 --- a/traffxml/traff_source.cpp +++ b/traffxml/traff_source.cpp @@ -136,6 +136,27 @@ HttpTraffSource::HttpTraffSource(TraffSourceManager & manager, std::string const , m_url(url) {} +void HttpTraffSource::Close() +{ + std::string data; + { + std::lock_guard lock(m_mutex); + + if (m_subscriptionId.empty()) + return; + data = ""; + m_subscriptionId.clear(); + } + + LOG(LDEBUG, ("Sending request:\n", data)); + + threads::SimpleThread thread([this, data]() { + TraffResponse response = HttpPost(m_url, data); + return; + }); + thread.detach(); +} + void HttpTraffSource::Subscribe(std::set & mwms) { std::string data = "\n\n" diff --git a/traffxml/traff_source.hpp b/traffxml/traff_source.hpp index 840d1b5d9..f38ddfef8 100644 --- a/traffxml/traff_source.hpp +++ b/traffxml/traff_source.hpp @@ -441,6 +441,15 @@ public: */ static void Create(TraffSourceManager & manager, std::string const & url); + /** + * @brief Prepares the HTTP traffic source for unloading. + * + * If there is still an active subscription, it unsubscribes, but without processing the result + * received from the service. Otherwise, teardown is a no-op. + */ + // TODO move this to the parent class and override it here? + void Close(); + /** * @brief Subscribes to a traffic service. *