From 3fc8e2ecd544194652621004c78e70391ad8db32 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 3 Sep 2019 18:44:56 +0300 Subject: [PATCH] [android] Added realtime statistics for guides --- 3party/Alohalytics | 2 +- .../com/mapswithme/maps/PrivateVariables.cpp | 8 ++ .../maps/bookmarks/data/BookmarkManager.cpp | 18 +++ .../com/mapswithme/maps/PrivateVariables.java | 2 + .../maps/bookmarks/BookmarksListFragment.java | 4 + .../CachedBookmarkCategoriesFragment.java | 11 ++ .../maps/bookmarks/data/BookmarkManager.java | 15 +++ .../purchase/AdsRemovalPurchaseDialog.java | 2 +- .../purchase/BookmarkPaymentFragment.java | 2 +- .../BookmarkSubscriptionFragment.java | 3 +- .../maps/widget/placepage/PlacePageView.java | 3 +- .../util/statistics/Statistics.java | 122 ++++++++++++++---- iphone/Maps/Common/Statistics/Statistics.mm | 3 +- map/bookmark_manager.cpp | 31 +++-- map/bookmark_manager.hpp | 4 + map/framework.cpp | 15 +++ 16 files changed, 206 insertions(+), 39 deletions(-) diff --git a/3party/Alohalytics b/3party/Alohalytics index 98e8f7dfbc..7dfbee9ba9 160000 --- a/3party/Alohalytics +++ b/3party/Alohalytics @@ -1 +1 @@ -Subproject commit 98e8f7dfbc9103ed8371a9c6bd180b4a49eed333 +Subproject commit 7dfbee9ba94f918836c276b4eee920883a6c1fb6 diff --git a/android/jni/com/mapswithme/maps/PrivateVariables.cpp b/android/jni/com/mapswithme/maps/PrivateVariables.cpp index 1e43642598..dace9a5985 100644 --- a/android/jni/com/mapswithme/maps/PrivateVariables.cpp +++ b/android/jni/com/mapswithme/maps/PrivateVariables.cpp @@ -2,6 +2,8 @@ #include "android/jni/com/mapswithme/core/jni_helper.hpp" +#include "base/url_helpers.hpp" + #include #include @@ -14,6 +16,12 @@ extern "C" return env->NewStringUTF(ALOHALYTICS_URL); } + JNIEXPORT jstring JNICALL + Java_com_mapswithme_maps_PrivateVariables_alohalyticsRealtimeUrl(JNIEnv * env, jclass clazz) + { + return env->NewStringUTF(base::url::Join(ALOHALYTICS_URL, "realtime").c_str()); + } + JNIEXPORT jstring JNICALL Java_com_mapswithme_maps_PrivateVariables_flurryKey(JNIEnv * env, jclass clazz) { diff --git a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp index e8f31fef2e..402f3f1575 100644 --- a/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp +++ b/android/jni/com/mapswithme/maps/bookmarks/data/BookmarkManager.cpp @@ -11,6 +11,8 @@ #include "platform/preferred_languages.hpp" +#include "base/string_utils.hpp" + #include using namespace std::placeholders; @@ -1078,6 +1080,22 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeResetInvalidCatego frm()->GetBookmarkManager().ResetInvalidCategories(); } +JNIEXPORT jstring JNICALL +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGuidesIds(JNIEnv * env, jobject) +{ + auto & bm = frm()->GetBookmarkManager(); + auto const guides = bm.GetCategoriesFromCatalog( + std::bind(&BookmarkManager::IsGuide, std::placeholders::_1)); + return ToJavaString(env, strings::JoinStrings(guides.begin(), guides.end(), ',')); +} + +JNIEXPORT jboolean JNICALL +Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeIsGuide(JNIEnv * env, jobject, + jint accessRulesIndex) +{ + return static_cast(BookmarkManager::IsGuide(static_cast(accessRulesIndex))); +} + JNIEXPORT jobjectArray JNICALL Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeGetBookmarkCategories(JNIEnv *env, jobject thiz) diff --git a/android/src/com/mapswithme/maps/PrivateVariables.java b/android/src/com/mapswithme/maps/PrivateVariables.java index d381ecd51e..35938cb31e 100644 --- a/android/src/com/mapswithme/maps/PrivateVariables.java +++ b/android/src/com/mapswithme/maps/PrivateVariables.java @@ -10,6 +10,8 @@ public class PrivateVariables @NonNull public static native String alohalyticsUrl(); @NonNull + public static native String alohalyticsRealtimeUrl(); + @NonNull public static native String flurryKey(); @NonNull public static native String appsFlyerKey(); diff --git a/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java b/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java index 4e960e43fe..2bb0c54ecf 100644 --- a/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java +++ b/android/src/com/mapswithme/maps/bookmarks/BookmarksListFragment.java @@ -512,12 +512,16 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment params) + { + trackEvent(name, params, STATISTICS_CHANNEL_DEFAULT); + } + + public void trackEvent(@NonNull String name, @NonNull Map params, + @StatisticsChannel int channel) { if (mEnabled) - org.alohalytics.Statistics.logEvent(name, params); + org.alohalytics.Statistics.logEvent(name, params, channel); mMediator.getEventLogger().logEvent(name, params); } - public void trackEvent(@NonNull String name, @Nullable Location location, @NonNull Map params) + public void trackEvent(@NonNull String name, @Nullable Location location, + @NonNull Map params) + { + trackEvent(name, location, params, STATISTICS_CHANNEL_DEFAULT); + } + + public void trackEvent(@NonNull String name, @Nullable Location location, + @NonNull Map params, @StatisticsChannel int channel) { List eventDictionary = new ArrayList(); for (Map.Entry entry : params.entrySet()) @@ -785,14 +825,20 @@ public enum Statistics params.put("lon", (location == null ? "N/A" : String.valueOf(location.getLongitude()))); if (mEnabled) - org.alohalytics.Statistics.logEvent(name, eventDictionary.toArray(new String[0]), location); + org.alohalytics.Statistics.logEvent(name, eventDictionary.toArray(new String[0]), location, channel); mMediator.getEventLogger().logEvent(name, params); } public void trackEvent(@NonNull String name, @NonNull ParameterBuilder builder) { - trackEvent(name, builder.get()); + trackEvent(name, builder.get(), STATISTICS_CHANNEL_DEFAULT); + } + + public void trackEvent(@NonNull String name, @NonNull ParameterBuilder builder, + @StatisticsChannel int channel) + { + trackEvent(name, builder.get(), channel); } public void startActivity(Activity activity) @@ -995,22 +1041,22 @@ public enum Statistics @NonNull MapObject mapObject) { String provider = restaurant.getType() == Sponsored.TYPE_OPENTABLE ? OPENTABLE : "Unknown restaurant"; - Statistics.INSTANCE.trackEvent(eventName, LocationHelper.INSTANCE.getLastKnownLocation(), - Statistics.params().add(PROVIDER, provider) - .add(RESTAURANT, restaurant.getId()) - .add(RESTAURANT_LAT, mapObject.getLat()) - .add(RESTAURANT_LON, mapObject.getLon()).get()); + trackEvent(eventName, LocationHelper.INSTANCE.getLastKnownLocation(), + Statistics.params().add(PROVIDER, provider) + .add(RESTAURANT, restaurant.getId()) + .add(RESTAURANT_LAT, mapObject.getLat()) + .add(RESTAURANT_LON, mapObject.getLon()).get()); } public void trackHotelEvent(@NonNull String eventName, @NonNull Sponsored hotel, @NonNull MapObject mapObject) { String provider = hotel.getType() == Sponsored.TYPE_BOOKING ? BOOKING_COM : "Unknown hotel"; - Statistics.INSTANCE.trackEvent(eventName, LocationHelper.INSTANCE.getLastKnownLocation(), - Statistics.params().add(PROVIDER, provider) - .add(HOTEL, hotel.getId()) - .add(HOTEL_LAT, mapObject.getLat()) - .add(HOTEL_LON, mapObject.getLon()).get()); + trackEvent(eventName, LocationHelper.INSTANCE.getLastKnownLocation(), + Statistics.params().add(PROVIDER, provider) + .add(HOTEL, hotel.getId()) + .add(HOTEL_LAT, mapObject.getLat()) + .add(HOTEL_LON, mapObject.getLon()).get()); } public void trackBookHotelEvent(@NonNull Sponsored hotel, @NonNull MapObject mapObject) @@ -1342,7 +1388,7 @@ public enum Statistics @NonNull MapObject mapObject) { // Here we code category by means of rating. - Statistics.INSTANCE.trackEvent(eventName, LocationHelper.INSTANCE.getLastKnownLocation(), + trackEvent(eventName, LocationHelper.INSTANCE.getLastKnownLocation(), Statistics.params().add(PROVIDER, convertToSponsor(sponsoredObj)) .add(CATEGORY, sponsoredObj.getRating()) .add(OBJECT_LAT, mapObject.getLat()) @@ -1567,12 +1613,19 @@ public enum Statistics { trackEvent(INAPP_PURCHASE_PREVIEW_SHOW, params().add(VENDOR, vendor) .add(PRODUCT, productId) - .add(PURCHASE, purchaseId)); + .add(PURCHASE, purchaseId), + STATISTICS_CHANNEL_REALTIME); } public void trackPurchaseEvent(@NonNull String event, @NonNull String purchaseId) { - trackEvent(event, params().add(PURCHASE, purchaseId)); + trackPurchaseEvent(event, purchaseId, STATISTICS_CHANNEL_DEFAULT); + } + + public void trackPurchaseEvent(@NonNull String event, @NonNull String purchaseId, + @StatisticsChannel int channel) + { + trackEvent(event, params().add(PURCHASE, purchaseId), channel); } public void trackPurchasePreviewSelect(@NonNull String purchaseId, @NonNull String productId) @@ -1632,18 +1685,39 @@ public enum Statistics public void trackPurchaseProductDelivered(@NonNull String purchaseId, @NonNull String vendor) { trackEvent(INAPP_PURCHASE_PRODUCT_DELIVERED, params().add(VENDOR, vendor) - .add(PURCHASE, purchaseId)); + .add(PURCHASE, purchaseId), + STATISTICS_CHANNEL_REALTIME); } public void trackTipsEvent(@NonNull String eventName, int type) { - Statistics.INSTANCE.trackEvent(eventName, params().add(TYPE, type)); + trackEvent(eventName, params().add(TYPE, type)); } public void trackTipsClose(int type) { - Statistics.INSTANCE.trackEvent(TIPS_TRICKS_CLOSE, params().add(TYPE, type) - .add(OPTION, OFFSCREEEN)); + trackEvent(TIPS_TRICKS_CLOSE, params().add(TYPE, type).add(OPTION, OFFSCREEEN)); + } + + public void trackGuidesShown(@NonNull String serverIds) + { + if (!serverIds.isEmpty()) + trackEvent(GUIDES_SHOWN, params().add(SERVER_IDS, serverIds), STATISTICS_CHANNEL_REALTIME); + } + + public void trackGuideOpen(@NonNull String serverId) + { + trackEvent(GUIDES_OPEN, params().add(SERVER_ID, serverId), STATISTICS_CHANNEL_REALTIME); + } + + public void trackGuideBookmarkSelect(@NonNull String serverId) + { + trackEvent(GUIDES_BOOKMARK_SELECT, params().add(SERVER_ID, serverId), STATISTICS_CHANNEL_REALTIME); + } + + public void trackGuideTrackSelect(@NonNull String serverId) + { + trackEvent(GUIDES_TRACK_SELECT, params().add(SERVER_ID, serverId), STATISTICS_CHANNEL_REALTIME); } public static ParameterBuilder params() diff --git a/iphone/Maps/Common/Statistics/Statistics.mm b/iphone/Maps/Common/Statistics/Statistics.mm index 75c3935d8d..8f40b25cce 100644 --- a/iphone/Maps/Common/Statistics/Statistics.mm +++ b/iphone/Maps/Common/Statistics/Statistics.mm @@ -55,7 +55,8 @@ void checkFlurryLogStatus(FlurryEventRecordStatus status) [MRMyTracker setupTracker]; } - [Alohalytics setup:@(ALOHALYTICS_URL) withLaunchOptions:launchOptions]; + [Alohalytics setup:@[@(ALOHALYTICS_URL), [NSString stringWithFormat:@"%@/%@", @(ALOHALYTICS_URL), @"realtime"]] + withLaunchOptions:launchOptions]; } // Always call Facebook method, looks like it is required to handle some url schemes and sign on scenarios. return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 407740f51b..bdfa0f0a89 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -995,6 +995,25 @@ std::string BookmarkManager::GetLocalizedRegionAddress(m2::PointD const & pt) return m_regionAddressGetter->GetLocalizedRegionAddress(pt); } +std::vector BookmarkManager::GetCategoriesFromCatalog(AccessRulesFilter && filter) const +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + std::vector result; + for (auto const & c : m_categories) + { + if (!filter || filter(c.second->GetCategoryData().m_accessRules)) + result.emplace_back(c.second->GetServerId()); + } + return result; +} + +// static +bool BookmarkManager::IsGuide(kml::AccessRules accessRules) +{ + return accessRules == kml::AccessRules::Public || accessRules == kml::AccessRules::Paid || + accessRules == kml::AccessRules::P2P; +} + void BookmarkManager::PrepareBookmarksAddresses(std::vector & bookmarksForSort, AddressesCollection & newAddresses) { @@ -2720,15 +2739,9 @@ void BookmarkManager::SetAllCategoriesVisibility(CategoryFilterType const filter std::vector BookmarkManager::GetAllPaidCategoriesIds() const { - CHECK_THREAD_CHECKER(m_threadChecker, ()); - std::vector ids; - for (auto const & category : m_categories) - { - if (category.second->GetCategoryData().m_accessRules != kml::AccessRules::Paid) - continue; - ids.emplace_back(category.second->GetServerId()); - } - return ids; + return GetCategoriesFromCatalog([](kml::AccessRules accessRules) { + return accessRules == kml::AccessRules::Paid; + }); } bool BookmarkManager::CanConvert() const diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 446d439555..e9c0949c69 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -439,6 +439,10 @@ public: static std::string GetSortedByTimeBlockName(SortedByTimeBlockType blockType); std::string GetLocalizedRegionAddress(m2::PointD const & pt); + using AccessRulesFilter = std::function; + std::vector GetCategoriesFromCatalog(AccessRulesFilter && filter) const; + static bool IsGuide(kml::AccessRules accessRules); + private: class MarksChangesTracker : public df::UserMarksProvider { diff --git a/map/framework.cpp b/map/framework.cpp index 81665965cd..687e3fcb36 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -2520,6 +2520,21 @@ void Framework::OnTapEvent(TapEvent const & tapEvent) alohalytics::Stats::Instance().LogEvent("$SelectMapObject", kv, alohalytics::Location::FromLatLon(ll.m_lat, ll.m_lon)); + // Send realtime statistics about bookmark selection. + if (info.IsBookmark()) + { + auto const serverId = m_bmManager->GetCategoryServerId(info.GetBookmarkCategoryId()); + if (!serverId.empty()) + { + auto const accessRules = m_bmManager->GetCategoryData(info.GetBookmarkCategoryId()).m_accessRules; + if (BookmarkManager::IsGuide(accessRules)) + { + alohalytics::TStringMap params = {{"server_id", serverId}}; + alohalytics::Stats::Instance().LogEvent("Map_GuideBookmark_open", params, alohalytics::kAllChannels); + } + } + } + if (info.GetSponsoredType() == SponsoredType::Booking) { GetPlatform().GetMarketingService().SendPushWooshTag(marketing::kBookHotelOnBookingComDiscovered);