diff options
author | r.kuznetsov <r.kuznetsov@corp.mail.ru> | 2018-08-15 16:20:37 +0300 |
---|---|---|
committer | Daria Volvenkova <d.volvenkova@corp.mail.ru> | 2018-08-17 15:26:10 +0300 |
commit | 515abeed2a658d13864d15c80463f53845738912 (patch) | |
tree | 8f1b718ba312ed47a60cbc64f34d9f4b2f31a8cc /map | |
parent | 93d41ed31836c9302b4589e1f7c0521e748c87ef (diff) |
[Core] Added subscription
Diffstat (limited to 'map')
-rw-r--r-- | map/CMakeLists.txt | 2 | ||||
-rw-r--r-- | map/framework.cpp | 44 | ||||
-rw-r--r-- | map/framework.hpp | 8 | ||||
-rw-r--r-- | map/local_ads_manager.cpp | 64 | ||||
-rw-r--r-- | map/local_ads_manager.hpp | 13 | ||||
-rw-r--r-- | map/subscription.cpp | 60 | ||||
-rw-r--r-- | map/subscription.hpp | 30 |
7 files changed, 203 insertions, 18 deletions
diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index 550ed86213..667095dc12 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -90,6 +90,8 @@ set( search_mark.cpp search_mark.hpp search_product_info.hpp + subscription.cpp + subscription.hpp taxi_delegate.cpp taxi_delegate.hpp track.cpp diff --git a/map/framework.cpp b/map/framework.cpp index 4cae3a1207..bf59ddf866 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -388,6 +388,7 @@ Framework::Framework(FrameworkParams const & params) }) , m_lastReportedCountry(kInvalidCountryId) , m_popularityLoader(m_model.GetDataSource()) + , m_subscription(std::make_unique<Subscription>()) { m_startBackgroundTime = my::Timer::LocalTime(); @@ -468,7 +469,10 @@ Framework::Framework(FrameworkParams const & params) // Local ads manager should be initialized after storage initialization. if (params.m_enableLocalAds) - m_localAdsManager.Startup(m_bmManager.get()); + { + m_localAdsManager.Startup(m_bmManager.get(), m_subscription->IsActive()); + m_subscription->Register(&m_localAdsManager); + } m_routingManager.SetRouterImpl(RouterType::Vehicle); @@ -496,12 +500,18 @@ Framework::Framework(FrameworkParams const & params) InitTransliteration(); LOG(LDEBUG, ("Transliterators initialized")); + + m_subscription->Validate(); } Framework::~Framework() { m_threadRunner.reset(); + // Must be destroyed implicitly at the start of destruction, + // since it stores raw pointers to other subsystems. + m_subscription.reset(); + osm::Editor & editor = osm::Editor::Instance(); editor.SetDelegate({}); @@ -513,7 +523,7 @@ Framework::~Framework() m_model.SetOnMapDeregisteredCallback(nullptr); m_user.ClearSubscribers(); - // Must be destroyed implicitly since it stores reference to m_user. + // Must be destroyed implicitly, since it stores reference to m_user. m_bmManager.reset(); } @@ -865,7 +875,7 @@ void Framework::FillInfoFromFeatureType(FeatureType & ft, place_page::Info & inf info.SetBookingSearchUrl(url); LOG(LINFO, (url)); } - else if (PartnerChecker::Instance()(ft)) + else if (m_subscription && !m_subscription->IsActive() && PartnerChecker::Instance()(ft)) { info.SetSponsoredType(place_page::SponsoredType::Partner); auto const partnerIndex = PartnerChecker::Instance().GetPartnerIndex(ft); @@ -1489,11 +1499,14 @@ search::DisplayedCategories const & Framework::GetDisplayedCategories() city = m_cityFinder->GetCityName(*position, StringUtf8Multilang::kEnglishCode); // Apply sponsored modifiers. - std::tuple<LuggageHeroModifier> modifiers(city); - my::for_each_in_tuple(modifiers, [&](size_t, SponsoredCategoryModifier & modifier) + if (m_subscription && !m_subscription->IsActive()) { - m_displayedCategories->Modify(modifier); - }); + std::tuple<LuggageHeroModifier> modifiers(city); + my::for_each_in_tuple(modifiers, [&](size_t, SponsoredCategoryModifier & modifier) + { + m_displayedCategories->Modify(modifier); + }); + } return *m_displayedCategories; } @@ -1519,7 +1532,9 @@ void Framework::SelectSearchResult(search::Result const & result, bool animation case Result::Type::PureSuggest: ASSERT(false, ("Suggests should not be here.")); return; } - info.SetAdsEngine(m_adsEngine.get()); + if (m_subscription && !m_subscription->IsActive()) + info.SetAdsEngine(m_adsEngine.get()); + SetPlacePageLocation(info); m2::PointD const center = info.GetMercator(); if (m_drapeEngine != nullptr) @@ -1721,6 +1736,13 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::GraphicsContextFactory> contextFac }); }; + auto filterFeatureFn = [this](FeatureType & ft) -> bool + { + if (m_subscription && !m_subscription->IsActive()) + return false; + return PartnerChecker::Instance().IsFakeObject(ft); + }; + auto overlaysShowStatsFn = [this](list<df::OverlayShowEvent> && events) { if (events.empty()) @@ -1763,7 +1785,8 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::GraphicsContextFactory> contextFac df::DrapeEngine::Params p( params.m_apiVersion, contextFactory, dp::Viewport(0, 0, params.m_surfaceWidth, params.m_surfaceHeight), - df::MapDataProvider(idReadFn, featureReadFn, isCountryLoadedByNameFn, updateCurrentCountryFn), + df::MapDataProvider(move(idReadFn), move(featureReadFn), move(filterFeatureFn), + move(isCountryLoadedByNameFn), move(updateCurrentCountryFn)), params.m_hints, params.m_visualScale, fontsScaleFactor, move(params.m_widgetsInitInfo), make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState), move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, @@ -2315,7 +2338,8 @@ df::SelectionShape::ESelectedObject Framework::OnTapEventImpl(TapEvent const & t return df::SelectionShape::OBJECT_MY_POSITION; } - outInfo.SetAdsEngine(m_adsEngine.get()); + if (m_subscription && !m_subscription->IsActive()) + outInfo.SetAdsEngine(m_adsEngine.get()); UserMark const * mark = FindUserMarkInTapPosition(tapInfo); if (mark != nullptr) diff --git a/map/framework.hpp b/map/framework.hpp index c7c3beec1c..5faddb1d88 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -15,6 +15,7 @@ #include "map/routing_mark.hpp" #include "map/search_api.hpp" #include "map/search_mark.hpp" +#include "map/subscription.hpp" #include "map/track.hpp" #include "map/traffic_manager.hpp" #include "map/transit/transit_reader.hpp" @@ -871,4 +872,11 @@ public: private: // m_discoveryManager must be bellow m_searchApi, m_viatorApi, m_localsApi unique_ptr<discovery::Manager> m_discoveryManager; + +public: + std::unique_ptr<Subscription> const & GetSubscription() const { return m_subscription; } + std::unique_ptr<Subscription> & GetSubscription() { return m_subscription; } + +private: + std::unique_ptr<Subscription> m_subscription; }; diff --git a/map/local_ads_manager.cpp b/map/local_ads_manager.cpp index a500b22848..7401ca5206 100644 --- a/map/local_ads_manager.cpp +++ b/map/local_ads_manager.cpp @@ -282,6 +282,7 @@ LocalAdsManager::LocalAdsManager(GetMwmsByRectFn && getMwmsByRectFn, , m_getMwmIdByNameFn(std::move(getMwmIdByName)) , m_readFeaturesFn(std::move(readFeaturesFn)) , m_getFeatureByIdFn(std::move(getFeatureByIDFn)) + , m_isStarted(false) , m_bmManager(nullptr) { CHECK(m_getMwmsByRectFn != nullptr, ()); @@ -290,14 +291,21 @@ LocalAdsManager::LocalAdsManager(GetMwmsByRectFn && getMwmsByRectFn, CHECK(m_getFeatureByIdFn != nullptr, ()); } -void LocalAdsManager::Startup(BookmarkManager * bmManager) +void LocalAdsManager::Startup(BookmarkManager * bmManager, bool isEnabled) { + m_isEnabled = isEnabled; FillSupportedTypes(); + m_bmManager = bmManager; - GetPlatform().RunTask(Platform::Thread::File, [this, bmManager] - { - m_bmManager = bmManager; + if (isEnabled) + Start(); +} +void LocalAdsManager::Start() +{ + m_isStarted = true; + GetPlatform().RunTask(Platform::Thread::File, [this] + { local_ads::IconsInfo::Instance().SetSourceFile(kLocalAdsSymbolsFile); std::string const campaignFile = GetPath(kCampaignFile); @@ -319,8 +327,9 @@ void LocalAdsManager::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine) void LocalAdsManager::UpdateViewport(ScreenBase const & screen) { auto const connectionStatus = GetPlatform().ConnectionStatus(); - if (kServerUrl.empty() || connectionStatus == Platform::EConnectionType::CONNECTION_NONE || - df::GetZoomLevel(screen.GetScale()) < kRequestMinZoomLevel) + if (!m_isStarted || !m_isEnabled || kServerUrl.empty() || + connectionStatus == Platform::EConnectionType::CONNECTION_NONE || + df::GetZoomLevel(screen.GetScale()) < kRequestMinZoomLevel) { return; } @@ -646,6 +655,49 @@ std::string LocalAdsManager::GetCompanyUrl(FeatureID const & featureId) const return MakeCampaignPageURL(featureId); } +void LocalAdsManager::OnSubscriptionChanged(bool isActive) +{ + bool enabled = !isActive; + if (m_isEnabled == enabled) + return; + + m_isEnabled = enabled; + if (enabled) + { + if (!m_isStarted) + Start(); + else + Invalidate(); + } + else + { + GetPlatform().RunTask(Platform::Thread::File, [this] + { + // Clear campaigns data. + { + std::lock_guard<std::mutex> lock(m_campaignsMutex); + m_campaigns.clear(); + m_info.clear(); + m_failedDownloads.clear(); + m_downloadingMwms.clear(); + } + + // Clear features cache. + { + std::lock_guard<std::mutex> lock(m_featuresCacheMutex); + m_featuresCache.clear(); + } + + // Clear all graphics. + DeleteAllLocalAdsMarks(m_bmManager); + m_drapeEngine.SafeCall(&df::DrapeEngine::RemoveAllCustomFeatures); + }); + + // Disable statistics collection. + m_statistics.SetEnabled(false); + } +} + bool LocalAdsManager::BackoffStats::CanRetry() const { return !m_fileIsAbsent && m_attemptsCount < kMaxDownloadingAttempts && diff --git a/map/local_ads_manager.hpp b/map/local_ads_manager.hpp index 6a28ba4eb8..e46bd00776 100644 --- a/map/local_ads_manager.hpp +++ b/map/local_ads_manager.hpp @@ -1,5 +1,7 @@ #pragma once +#include "map/subscription.hpp" + #include "local_ads/statistics.hpp" #include "drape_frontend/custom_features_context.hpp" @@ -32,7 +34,7 @@ class TypesHolder; class BookmarkManager; -class LocalAdsManager final +class LocalAdsManager : public SubscriptionListener { public: using GetMwmsByRectFn = std::function<std::vector<MwmSet::MwmId>(m2::RectD const &)>; @@ -47,7 +49,7 @@ public: ReadFeaturesFn && readFeaturesFn, GetFeatureByIdFn && getFeatureByIDFn); LocalAdsManager(LocalAdsManager && /* localAdsManager */) = default; - void Startup(BookmarkManager * bmManager); + void Startup(BookmarkManager * bmManager, bool isEnabled); void SetDrapeEngine(ref_ptr<df::DrapeEngine> engine); void UpdateViewport(ScreenBase const & screen); @@ -64,6 +66,8 @@ public: std::string GetCompanyUrl(FeatureID const & featureId) const; + void OnSubscriptionChanged(bool isActive) override; + private: enum class RequestType { @@ -72,6 +76,8 @@ private: }; using Request = std::pair<MwmSet::MwmId, RequestType>; + void Start(); + void ProcessRequests(std::set<Request> && campaignMwms); void ReadCampaignFile(std::string const & campaignFile); @@ -93,6 +99,8 @@ private: ReadFeaturesFn const m_readFeaturesFn; GetFeatureByIdFn const m_getFeatureByIdFn; + std::atomic<bool> m_isStarted; + std::atomic<BookmarkManager *> m_bmManager; df::DrapeEngineSafePtr m_drapeEngine; @@ -134,4 +142,5 @@ private: std::set<MwmSet::MwmId> m_downloadingMwms; local_ads::Statistics m_statistics; + std::atomic<bool> m_isEnabled; }; diff --git a/map/subscription.cpp b/map/subscription.cpp new file mode 100644 index 0000000000..437f232589 --- /dev/null +++ b/map/subscription.cpp @@ -0,0 +1,60 @@ +#include "map/subscription.hpp" + +#include "platform/platform.hpp" + +#include "coding/sha1.hpp" + +#include "base/assert.hpp" + +namespace +{ +std::string const kSubscriptionId = "SubscriptionId"; + +std::string GetSubscriptionId() +{ + return coding::SHA1::CalculateBase64ForString(GetPlatform().UniqueClientId()); +} +} // namespace + +Subscription::Subscription() +{ + std::string id; + if (GetPlatform().GetSecureStorage().Load(kSubscriptionId, id)) + m_subscriptionId = id; + m_isActive = (GetSubscriptionId() == m_subscriptionId); +} + +void Subscription::Register(SubscriptionListener * listener) +{ + CHECK(listener != nullptr, ()); + CHECK_THREAD_CHECKER(m_threadChecker, ()); + m_listeners.emplace_back(listener); + listener->OnSubscriptionChanged(IsActive()); +} + +bool Subscription::IsActive() const +{ + return m_isActive; +} + +void Subscription::Validate() +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + + //TODO: check on server. + bool isValid = false; + + m_isActive = isValid; + if (isValid) + { + m_subscriptionId = GetSubscriptionId(); + GetPlatform().GetSecureStorage().Save(kSubscriptionId, m_subscriptionId); + } + else + { + GetPlatform().GetSecureStorage().Remove(kSubscriptionId); + } + + for (auto & listener : m_listeners) + listener->OnSubscriptionChanged(isValid); +} diff --git a/map/subscription.hpp b/map/subscription.hpp new file mode 100644 index 0000000000..793135c231 --- /dev/null +++ b/map/subscription.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "base/thread_checker.hpp" + +#include <atomic> +#include <string> +#include <vector> + +class SubscriptionListener +{ +public: + virtual ~SubscriptionListener() = default; + virtual void OnSubscriptionChanged(bool isActive) = 0; +}; + +class Subscription +{ +public: + Subscription(); + void Register(SubscriptionListener * listener); + bool IsActive() const; + void Validate(); + +private: + std::atomic<bool> m_isActive; + std::string m_subscriptionId; + std::vector<SubscriptionListener *> m_listeners; + + ThreadChecker m_threadChecker; +}; |