diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index 7548f668bd..9b867b6c9b 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -81,6 +81,8 @@ set( guides_on_map_delegate.hpp isolines_manager.cpp isolines_manager.hpp + layers_statistics.cpp + layers_statistics.hpp local_ads_manager.cpp local_ads_manager.hpp local_ads_mark.cpp diff --git a/map/framework.cpp b/map/framework.cpp index eb1c97fb75..85992fb770 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1512,8 +1512,12 @@ void Framework::EnterForeground() if (m_guidesManager.IsEnabled() && secondsInBackground / 60 / 60 > kGuidesEnabledInBackgroundMaxHours) { + auto const shownCount = m_guidesManager.GetShownGuidesCount(); m_guidesManager.SetEnabled(false); SaveGuidesEnabled(false); + + alohalytics::LogEvent("Map_Layers_deactivate", + {{"name", "guides"}, {"count", strings::to_string(shownCount)}}); } } diff --git a/map/guides_manager.cpp b/map/guides_manager.cpp index e4e3faafb2..aa5a6045c5 100644 --- a/map/guides_manager.cpp +++ b/map/guides_manager.cpp @@ -7,6 +7,7 @@ #include "drape_frontend/drape_engine.hpp" #include "drape_frontend/visual_params.hpp" +#include "platform/platform.hpp" #include "platform/preferred_languages.hpp" #include "geometry/intersection_score.hpp" @@ -26,6 +27,7 @@ auto constexpr kScaleEps = 0.1115; GuidesManager::GuidesManager(CloseGalleryFn && closeGalleryFn) : m_closeGallery(std::move(closeGalleryFn)) + , m_statistics("guides") { CHECK(m_closeGallery != nullptr, ()); } @@ -134,6 +136,9 @@ void GuidesManager::ChangeState(GuidesState newState) m_state = newState; if (m_onStateChanged != nullptr) m_onStateChanged(newState); + + if (m_shownGuides.empty()) + TrackStatistics(); } void GuidesManager::RequestGuides() @@ -331,12 +336,15 @@ void GuidesManager::OnClusterSelected(GuidesClusterMark const & mark, ScreenBase { m_drapeEngine.SafeCall(&df::DrapeEngine::Scale, 2.0, screen.GtoP(mark.GetPivot()), true /* isAnim */); + m_statistics.LogItemSelected(LayersStatistics::LayerItemType::Cluster); } void GuidesManager::OnGuideSelected() { if (m_onGalleryChanged) m_onGalleryChanged(false /* reload */); + + m_statistics.LogItemSelected(LayersStatistics::LayerItemType::Point); } void GuidesManager::UpdateActiveGuide() @@ -361,6 +369,16 @@ bool GuidesManager::IsRequestParamsInitialized() const return m_screen.GlobalRect().GetLocalRect().IsEmptyInterior() || m_zoom != 0; } +void GuidesManager::TrackStatistics() const +{ + if (m_state == GuidesState::HasData) + m_statistics.LogActivate(LayersStatistics::Status::Success); + else if (m_state == GuidesState::NoData) + m_statistics.LogActivate(LayersStatistics::Status::Unavailable); + else if (m_state == GuidesState::NetworkError || m_state == GuidesState::FatalNetworkError) + m_statistics.LogActivate(LayersStatistics::Status::Error); +} + std::string DebugPrint(GuidesManager::GuidesState state) { switch (state) diff --git a/map/guides_manager.hpp b/map/guides_manager.hpp index ff666665f1..ba794f2620 100644 --- a/map/guides_manager.hpp +++ b/map/guides_manager.hpp @@ -4,6 +4,7 @@ #include "map/catalog_headers_provider.hpp" #include "map/guides_marks.hpp" #include "map/guides_on_map_delegate.hpp" +#include "map/layers_statistics.hpp" #include "partners_api/guides_on_map_api.hpp" @@ -12,6 +13,7 @@ #include "geometry/rect2d.hpp" #include "geometry/screenbase.hpp" +#include #include #include #include @@ -120,6 +122,8 @@ private: bool IsRequestParamsInitialized() const; + void TrackStatistics() const; + CloseGalleryFn m_closeGallery; GuidesState m_state = GuidesState::Disabled; @@ -143,6 +147,7 @@ private: uint32_t m_nextMarkIndex = 0; std::unordered_set m_shownGuides; + LayersStatistics m_statistics; }; std::string DebugPrint(GuidesManager::GuidesState state); diff --git a/map/isolines_manager.cpp b/map/isolines_manager.cpp index aba69c34f5..a627d6718d 100644 --- a/map/isolines_manager.cpp +++ b/map/isolines_manager.cpp @@ -15,6 +15,7 @@ int constexpr kMinIsolinesZoom = 11; IsolinesManager::IsolinesManager(DataSource & dataSource, GetMwmsByRectFn const & getMwmsByRectFn) : m_dataSource(dataSource) , m_getMwmsByRectFn(getMwmsByRectFn) + , m_statistics("isolines") { CHECK(m_getMwmsByRectFn != nullptr, ()); } @@ -124,6 +125,7 @@ void IsolinesManager::UpdateState() bool available = false; bool expired = false; bool noData = false; + std::set mwmVersions; for (auto const & mwmId : m_lastMwms) { if (!mwmId.IsAlive()) @@ -136,6 +138,9 @@ void IsolinesManager::UpdateState() case Availability::ExpiredData: expired = true; break; case Availability::NoData: noData = true; break; } + + if (m_trackFirstSchemeData) + mwmVersions.insert(mwmId.GetInfo()->GetVersion()); } if (expired) @@ -143,13 +148,20 @@ void IsolinesManager::UpdateState() else if (!available && noData) ChangeState(IsolinesState::NoData); else + ChangeState(IsolinesState::Enabled); + + if (m_trackFirstSchemeData) { - if (available && m_trackFirstSchemeData) + if (available) { eye::Eye::Event::LayerShown(eye::Layer::Type::Isolines); + m_statistics.LogActivate(LayersStatistics::Status::Success, mwmVersions); m_trackFirstSchemeData = false; } - ChangeState(IsolinesState::Enabled); + else + { + m_statistics.LogActivate(LayersStatistics::Status::Unavailable, mwmVersions); + } } } diff --git a/map/isolines_manager.hpp b/map/isolines_manager.hpp index b6c3619237..52f286d7e0 100644 --- a/map/isolines_manager.hpp +++ b/map/isolines_manager.hpp @@ -1,5 +1,7 @@ #pragma once +#include "map/layers_statistics.hpp" + #include "drape_frontend/drape_engine_safe_ptr.hpp" #include "indexer/data_source.hpp" @@ -11,6 +13,7 @@ #include "geometry/rect2d.hpp" #include "geometry/screenbase.hpp" +#include #include #include #include @@ -88,6 +91,7 @@ private: std::vector m_lastMwms; mutable std::map m_mwmCache; bool m_trackFirstSchemeData = false; + LayersStatistics m_statistics; }; std::string DebugPrint(IsolinesManager::IsolinesState state); diff --git a/map/layers_statistics.cpp b/map/layers_statistics.cpp new file mode 100644 index 0000000000..301c4fa2aa --- /dev/null +++ b/map/layers_statistics.cpp @@ -0,0 +1,52 @@ +#include "map/layers_statistics.hpp" + +#include "base/assert.hpp" +#include "base/string_utils.hpp" + +#include "3party/Alohalytics/src/alohalytics.h" + +namespace +{ +std::string ToString(LayersStatistics::Status status) +{ + switch (status) + { + case LayersStatistics::Status::Success: return "success"; + case LayersStatistics::Status::Error: return "error"; + case LayersStatistics::Status::Unavailable: return "unavailable"; + } + UNREACHABLE(); +} + +std::string ToString(LayersStatistics::LayerItemType itemType) +{ + switch (itemType) + { + case LayersStatistics::LayerItemType::Point: return "point"; + case LayersStatistics::LayerItemType::Cluster: return "cluster"; + } + UNREACHABLE(); +} +} // namespace + +LayersStatistics::LayersStatistics(std::string const & layerName) + : m_layerName(layerName) +{ +} + +void LayersStatistics::LogActivate(Status status, + std::set const & mwmVersions /* = {} */) const +{ + alohalytics::TStringMap params = {{"name", m_layerName}, {"status", ToString(status)}}; + + if (!mwmVersions.empty()) + params.emplace("dataversion", strings::JoinAny(mwmVersions)); + + alohalytics::LogEvent("Map_Layers_activate", params); +} + +void LayersStatistics::LogItemSelected(LayerItemType itemType) const +{ + alohalytics::LogEvent("Map_Layers_item_selected", + {{"name", m_layerName}, {"type", ToString(itemType)}}); +} diff --git a/map/layers_statistics.hpp b/map/layers_statistics.hpp new file mode 100644 index 0000000000..d6a831af09 --- /dev/null +++ b/map/layers_statistics.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include + +class LayersStatistics +{ +public: + enum class Status + { + Success, + Error, + Unavailable, + }; + + enum class LayerItemType + { + Point, + Cluster, + }; + + explicit LayersStatistics(std::string const & layerName); + + void LogActivate(Status status, std::set const & mwmVersions = {}) const; + void LogItemSelected(LayerItemType itemType) const; + +private: + std::string m_layerName; +}; diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 89e26937a1..8bb7ec7f72 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -12,8 +12,6 @@ #include "platform/platform.hpp" -#include "3party/Alohalytics/src/alohalytics.h" - using namespace std::chrono; namespace @@ -53,6 +51,7 @@ TrafficManager::TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, size_t m , m_isRunning(true) , m_isPaused(false) , m_thread(&TrafficManager::ThreadRoutine, this) + , m_statistics("traffic") { CHECK(m_getMwmsByRectFn != nullptr, ()); } @@ -97,6 +96,7 @@ void TrafficManager::SetEnabled(bool enabled) return; Clear(); ChangeState(enabled ? TrafficState::Enabled : TrafficState::Disabled); + m_trackFirstSchemeData = enabled; } m_drapeEngine.SafeCall(&df::DrapeEngine::EnableTraffic, enabled); @@ -105,9 +105,6 @@ void TrafficManager::SetEnabled(bool enabled) { Invalidate(); GetPlatform().GetMarketingService().SendPushWooshTag(marketing::kTrafficDiscovered); - alohalytics::LogEvent( - "$TrafficEnabled", - alohalytics::TStringMap({{"dataVersion", strings::to_string(m_currentDataVersion.load())}})); } else { @@ -484,6 +481,7 @@ void TrafficManager::UpdateState() bool expiredData = false; bool noData = false; + std::set mwmVersions; for (MwmSet::MwmId const & mwmId : m_activeDrapeMwms) { auto it = m_mwmCache.find(mwmId); @@ -510,8 +508,12 @@ void TrafficManager::UpdateState() networkError = true; } } + + if (m_trackFirstSchemeData) + mwmVersions.insert(mwmId.GetInfo()->GetVersion()); } + auto const previousState = m_state.load(); if (networkError || maxPassedTime >= kNetworkErrorTimeout) ChangeState(TrafficState::NetworkError); else if (waiting) @@ -526,6 +528,9 @@ void TrafficManager::UpdateState() ChangeState(TrafficState::Outdated); else ChangeState(TrafficState::Enabled); + + if (previousState != m_state) + TrackStatistics(mwmVersions); } void TrafficManager::ChangeState(TrafficState newState) @@ -534,9 +539,6 @@ void TrafficManager::ChangeState(TrafficState newState) return; m_state = newState; - alohalytics::LogEvent( - "$TrafficChangeState", - alohalytics::TStringMap({{"state", DebugPrint(m_state.load())}})); GetPlatform().RunTask(Platform::Thread::Gui, [this, newState]() { @@ -575,6 +577,27 @@ void TrafficManager::SetSimplifiedColorScheme(bool simplified) m_drapeEngine.SafeCall(&df::DrapeEngine::SetSimplifiedTrafficColors, simplified); } +void TrafficManager::TrackStatistics(std::set const & mwmVersions) +{ + if (m_trackFirstSchemeData) + { + if (m_state == TrafficState::Enabled) + { + m_trackFirstSchemeData = false; + m_statistics.LogActivate(LayersStatistics::Status::Success, mwmVersions); + } + else if (m_state == TrafficState::NetworkError) + { + m_statistics.LogActivate(LayersStatistics::Status::Error, mwmVersions); + } + else if (m_state == TrafficState::NoData || m_state == TrafficState::ExpiredData || + m_state == TrafficState::ExpiredApp) + { + m_statistics.LogActivate(LayersStatistics::Status::Unavailable, mwmVersions); + } + } +} + std::string DebugPrint(TrafficManager::TrafficState state) { switch (state) diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index bd0ae5432a..768d6846e5 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -1,5 +1,7 @@ #pragma once +#include "map/layers_statistics.hpp" + #include "traffic/traffic_info.hpp" #include "drape_frontend/drape_engine_safe_ptr.hpp" @@ -7,18 +9,19 @@ #include "drape/pointers.hpp" +#include "indexer/mwm_set.hpp" + #include "geometry/point2d.hpp" #include "geometry/polyline2d.hpp" #include "geometry/screenbase.hpp" -#include "indexer/mwm_set.hpp" - #include "base/thread.hpp" #include #include #include #include +#include #include #include #include @@ -145,6 +148,8 @@ private: std::for_each(activeMwms.begin(), activeMwms.end(), std::forward(f)); } + void TrackStatistics(std::set const & mwmVersions); + GetMwmsByRectFn m_getMwmsByRectFn; traffic::TrafficObserver & m_observer; @@ -183,6 +188,9 @@ private: std::vector m_requestedMwms; std::mutex m_mutex; threads::SimpleThread m_thread; + + bool m_trackFirstSchemeData = false; + LayersStatistics m_statistics; }; extern std::string DebugPrint(TrafficManager::TrafficState state); diff --git a/map/transit/transit_reader.cpp b/map/transit/transit_reader.cpp index 0d0e71ec26..06a2e696d5 100644 --- a/map/transit/transit_reader.cpp +++ b/map/transit/transit_reader.cpp @@ -141,7 +141,10 @@ unique_ptr && ReadTransitTask::GetTransitInfo() TransitReadManager::TransitReadManager(DataSource & dataSource, TReadFeaturesFn const & readFeaturesFn, GetMwmsByRectFn const & getMwmsByRectFn) - : m_dataSource(dataSource), m_readFeaturesFn(readFeaturesFn), m_getMwmsByRectFn(getMwmsByRectFn) + : m_dataSource(dataSource) + , m_readFeaturesFn(readFeaturesFn) + , m_getMwmsByRectFn(getMwmsByRectFn) + , m_statistics("subway") { Start(); } @@ -241,6 +244,8 @@ void TransitReadManager::UpdateViewport(ScreenBase const & screen) m_lastActiveMwms.clear(); auto const currentTime = steady_clock::now(); + std::set mwmVersions; + TransitDisplayInfos newTransitData; for (auto const & mwmId : mwms) { @@ -257,6 +262,9 @@ void TransitReadManager::UpdateViewport(ScreenBase const & screen) { it->second.m_lastActiveTime = currentTime; } + + if (m_trackFirstSchemeData) + mwmVersions.insert(mwmId.GetInfo()->GetVersion()); } if (!newTransitData.empty()) @@ -298,13 +306,9 @@ void TransitReadManager::UpdateViewport(ScreenBase const & screen) } } - if (hasData && m_trackFirstSchemeData) - { - eye::Eye::Event::LayerShown(eye::Layer::Type::PublicTransport); - m_trackFirstSchemeData = false; - } - ChangeState(hasData ? TransitSchemeState::Enabled : TransitSchemeState::NoData); + + TrackStatistics(mwmVersions); } void TransitReadManager::ClearCache(MwmSet::MwmId const & mwmId) @@ -429,3 +433,20 @@ void TransitReadManager::ChangeState(TransitSchemeState newState) if (m_onStateChangedFn) m_onStateChangedFn(newState); } + +void TransitReadManager::TrackStatistics(std::set const & mwmVersions) +{ + if (m_trackFirstSchemeData) + { + if (m_state == TransitSchemeState::Enabled) + { + eye::Eye::Event::LayerShown(eye::Layer::Type::PublicTransport); + m_trackFirstSchemeData = false; + m_statistics.LogActivate(LayersStatistics::Status::Success, mwmVersions); + } + else + { + m_statistics.LogActivate(LayersStatistics::Status::Unavailable, mwmVersions); + } + } +} diff --git a/map/transit/transit_reader.hpp b/map/transit/transit_reader.hpp index aa1b4d06d9..983c620260 100644 --- a/map/transit/transit_reader.hpp +++ b/map/transit/transit_reader.hpp @@ -1,14 +1,16 @@ #pragma once -#include "transit/transit_display_info.hpp" +#include "map/layers_statistics.hpp" #include "drape_frontend/drape_engine_safe_ptr.hpp" -#include "geometry/screenbase.hpp" +#include "transit/transit_display_info.hpp" #include "indexer/data_source.hpp" #include "indexer/feature_decl.hpp" +#include "geometry/screenbase.hpp" + #include "base/thread.hpp" #include "base/thread_pool.hpp" @@ -118,6 +120,8 @@ private: void ShrinkCacheToAllowableSize(); void ClearCache(MwmSet::MwmId const & mwmId); + void TrackStatistics(std::set const & mwmVersions); + std::unique_ptr m_threadsPool; std::mutex m_mutex; @@ -153,4 +157,5 @@ private: bool m_isSchemeModeBlocked = false; std::pair m_currentModelView = {ScreenBase(), false /* initialized */}; bool m_trackFirstSchemeData = false; + LayersStatistics m_statistics; };