diff --git a/android/jni/com/mapswithme/maps/LightFramework.cpp b/android/jni/com/mapswithme/maps/LightFramework.cpp index aceca8849a..8aeb180655 100644 --- a/android/jni/com/mapswithme/maps/LightFramework.cpp +++ b/android/jni/com/mapswithme/maps/LightFramework.cpp @@ -22,20 +22,24 @@ Java_com_mapswithme_maps_LightFramework_nativeGetNumberUnsentUGC(JNIEnv * env, j } JNIEXPORT jobjectArray JNICALL -Java_com_mapswithme_maps_LightFramework_nativeGetLocalAdsFeatures(JNIEnv * env, jclass clazz, jdouble lat, jdouble lon, - jdouble radiusInMeters, jint maxCount) +Java_com_mapswithme_maps_LightFramework_nativeGetLocalAdsFeatures(JNIEnv * env, jclass clazz, + jdouble lat, jdouble lon, + jdouble radiusInMeters, + jint maxCount) { Framework framework(REQUEST_TYPE_LOCAL_ADS_FEATURES); - auto const features = framework.Get(lat, lon, radiusInMeters, maxCount); + auto const features = framework.Get(lat, lon, radiusInMeters, + maxCount); - static jclass const geoFenceFeatureClazz = jni::GetGlobalClassRef(env, - "com/mapswithme/maps/api/GeoFenceFeature"); + static jclass const geoFenceFeatureClazz = + jni::GetGlobalClassRef(env, "com/mapswithme/maps/geofence/GeoFenceFeature"); // Java signature : GeoFenceFeature(long mwmVersion, String countryId, int featureIndex, // double latitude, double longitude) static jmethodID const geoFenceFeatureConstructor = jni::GetConstructorID(env, geoFenceFeatureClazz, "(JLjava/lang/String;IDD)V"); - return jni::ToJavaArray(env, geoFenceFeatureClazz, features, [&](JNIEnv * jEnv, CampaignFeature const & data) + return jni::ToJavaArray(env, geoFenceFeatureClazz, features, [&](JNIEnv * jEnv, + CampaignFeature const & data) { jni::TScopedLocalRef const countryId(env, jni::ToJavaString(env, data.m_countryId)); return env->NewObject(geoFenceFeatureClazz, geoFenceFeatureConstructor, @@ -48,14 +52,16 @@ Java_com_mapswithme_maps_LightFramework_nativeGetLocalAdsFeatures(JNIEnv * env, } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_LightFramework_nativeLogLocalAdsEvent(JNIEnv * env, jclass clazz, jint type, - jdouble lat, jdouble lon, jint accuracyInMeters, - jlong mwmVersion, jstring countryId, jint featureIndex) +Java_com_mapswithme_maps_LightFramework_nativeLogLocalAdsEvent(JNIEnv * env, jclass clazz, + jint type, jdouble lat, jdouble lon, + jint accuracyInMeters, + jlong mwmVersion, jstring countryId, + jint featureIndex) { Framework framework(REQUEST_TYPE_LOCAL_ADS_STATISTICS); local_ads::Event event(static_cast(type), static_cast(mwmVersion), jni::ToNativeString(env, countryId), static_cast(featureIndex), - static_cast(1) /* zoom level*/, local_ads::Clock::now(), + static_cast(1) /* zoom level */, local_ads::Clock::now(), static_cast(lat), static_cast(lon), static_cast(accuracyInMeters)); framework.Get()->RegisterEvent(std::move(event)); diff --git a/android/src/com/mapswithme/maps/LightFramework.java b/android/src/com/mapswithme/maps/LightFramework.java index f75b329482..02df3a432d 100644 --- a/android/src/com/mapswithme/maps/LightFramework.java +++ b/android/src/com/mapswithme/maps/LightFramework.java @@ -2,14 +2,17 @@ package com.mapswithme.maps; import android.support.annotation.NonNull; -import com.mapswithme.maps.api.GeoFenceFeature; +import com.mapswithme.maps.geofence.GeoFenceFeature; public class LightFramework { public static native boolean nativeIsAuthenticated(); public static native int nativeGetNumberUnsentUGC(); + @NonNull public static native GeoFenceFeature[] nativeGetLocalAdsFeatures(double lat, double lon, - double radiusInMeters, int maxCount); - public static native void nativeLogLocalAdsEvent(int type, double lat, double lon, int accuracyInMeters, - long mwmVersion, @NonNull String countryId, int featureIndex); + double radiusInMeters, + int maxCount); + public static native void nativeLogLocalAdsEvent(int type, double lat, double lon, + int accuracyInMeters, long mwmVersion, + @NonNull String countryId, int featureIndex); } diff --git a/android/src/com/mapswithme/maps/api/GeoFenceFeature.java b/android/src/com/mapswithme/maps/api/GeoFenceFeature.java deleted file mode 100644 index b2670854a3..0000000000 --- a/android/src/com/mapswithme/maps/api/GeoFenceFeature.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mapswithme.maps.api; - -/** - * Represents CampaignFeature from core. - */ -public class GeoFenceFeature -{ - public final long mwmVersion; - public final String countryId; - public final int featureIndex; - public final double latitude; - public final double longitude; - - public GeoFenceFeature(long mwmVersion, String countryId, int featureIndex, - double latitude, double longitude) - { - this.mwmVersion = mwmVersion; - this.countryId = countryId; - this.featureIndex = featureIndex; - this.latitude = latitude; - this.longitude = longitude; - } -} diff --git a/android/src/com/mapswithme/maps/background/NotificationService.java b/android/src/com/mapswithme/maps/background/NotificationService.java index c6b9993906..0ee96c6959 100644 --- a/android/src/com/mapswithme/maps/background/NotificationService.java +++ b/android/src/com/mapswithme/maps/background/NotificationService.java @@ -44,19 +44,16 @@ public class NotificationService extends JobIntentService private boolean notifyIsNotAuthenticated() { - final boolean isAuthenticated = LightFramework.nativeIsAuthenticated(); - final int numberUnsentUgc = LightFramework.nativeGetNumberUnsentUGC(); - if (!PermissionsUtils.isExternalStorageGranted() || !NetworkPolicy.getCurrentNetworkUsageStatus() || - isAuthenticated || - numberUnsentUgc < MIN_COUNT_UNSENT_UGC) + LightFramework.nativeIsAuthenticated() || + LightFramework.nativeGetNumberUnsentUGC() < MIN_COUNT_UNSENT_UGC) { LOGGER.d(TAG, "Authentication notification is rejected. External storage granted: " + PermissionsUtils.isExternalStorageGranted() + ". Is user authenticated: " + - isAuthenticated + ". Current network usage status: " + + LightFramework.nativeIsAuthenticated() + ". Current network usage status: " + NetworkPolicy.getCurrentNetworkUsageStatus() + ". Number of unsent UGC: " + - numberUnsentUgc); + LightFramework.nativeGetNumberUnsentUGC()); return false; } diff --git a/android/src/com/mapswithme/maps/geofence/GeoFenceFeature.java b/android/src/com/mapswithme/maps/geofence/GeoFenceFeature.java new file mode 100644 index 0000000000..c91abea906 --- /dev/null +++ b/android/src/com/mapswithme/maps/geofence/GeoFenceFeature.java @@ -0,0 +1,52 @@ +package com.mapswithme.maps.geofence; + +import android.support.annotation.NonNull; + +/** + * Represents CampaignFeature from core. + */ +public class GeoFenceFeature +{ + private final long mwmVersion; + @NonNull + private final String countryId; + private final int featureIndex; + private final double latitude; + private final double longitude; + + public GeoFenceFeature(long mwmVersion, @NonNull String countryId, int featureIndex, + double latitude, double longitude) + { + this.mwmVersion = mwmVersion; + this.countryId = countryId; + this.featureIndex = featureIndex; + this.latitude = latitude; + this.longitude = longitude; + } + + public long getMwmVersion() + { + return mwmVersion; + } + + @NonNull + public String getCountryId() + { + return countryId; + } + + public int getFeatureIndex() + { + return featureIndex; + } + + public double getLatitude() + { + return latitude; + } + + public double getLongitude() + { + return longitude; + } +} diff --git a/local_ads/statistics.cpp b/local_ads/statistics.cpp index 2d65a3eefd..1d30f7a453 100644 --- a/local_ads/statistics.cpp +++ b/local_ads/statistics.cpp @@ -198,8 +198,6 @@ std::vector SerializeForServer(std::list const & even ASSERT(!events.empty(), ()); auto root = base::NewJSONObject(); ToJSONObject(*root, "userId", userId); - static std::string offlineId = GetPlatform().MacAddress(true /* md5Decoded */); - ToJSONObject(*root, "offlineId", offlineId); ToJSONObject(*root, "countryId", events.front().m_countryId); ToJSONObject(*root, "mwmVersion", events.front().m_mwmVersion); auto eventsNode = base::NewJSONArray(); diff --git a/map/local_ads_manager.cpp b/map/local_ads_manager.cpp index fb2f56e034..940eb00d0e 100644 --- a/map/local_ads_manager.cpp +++ b/map/local_ads_manager.cpp @@ -52,10 +52,11 @@ auto constexpr kMaxDownloadingAttempts = 5; auto constexpr kHiddenFeaturePriority = 1; -double constexpr kMinCheckDistanceInMeters = 10.0; +auto constexpr kMinCheckInterval = std::chrono::minutes(1); +double constexpr kMinCheckDistanceInMeters = 5.0; double constexpr kMinSearchRadiusInMeters = 20.0; +double constexpr kMaxAllowableAccuracyInMeters = 20.0; uint32_t constexpr kMaxHitCount = 3; -auto const kMinCheckInterval = std::chrono::minutes(1); void SerializeCampaign(FileWriter & writer, std::string const & countryName, LocalAdsManager::Timestamp const & ts, @@ -270,7 +271,7 @@ void LocalAdsManager::Start() // Read persistence data. ReadCampaignFile(campaignFile); - Invalidate(); + InvalidateImpl(); }); m_statistics.Startup(); @@ -588,26 +589,32 @@ void LocalAdsManager::WriteFeaturesFile(std::string const & featuresFile) void LocalAdsManager::Invalidate() { + m_lastMwms.clear(); GetPlatform().RunTask(Platform::Thread::File, [this] { - DeleteAllLocalAdsMarks(); - m_drapeEngine.SafeCall(&df::DrapeEngine::RemoveAllCustomFeatures); - - CampaignData campaignData; - { - std::lock_guard lock(m_campaignsMutex); - for (auto const & info : m_info) - { - auto data = ParseCampaign(info.second.m_data, m_getMwmIdByNameFn(info.first), - info.second.m_created, m_getFeatureByIdFn); - campaignData.insert(data.begin(), data.end()); - } - } - UpdateFeaturesCache(ReadCampaignFeatures(campaignData)); - CreateLocalAdsMarks(std::move(campaignData)); + InvalidateImpl(); }); } +void LocalAdsManager::InvalidateImpl() +{ + DeleteAllLocalAdsMarks(); + m_drapeEngine.SafeCall(&df::DrapeEngine::RemoveAllCustomFeatures); + + CampaignData campaignData; + { + std::lock_guard lock(m_campaignsMutex); + for (auto const & info : m_info) + { + auto data = ParseCampaign(info.second.m_data, m_getMwmIdByNameFn(info.first), + info.second.m_created, m_getFeatureByIdFn); + campaignData.insert(data.begin(), data.end()); + } + } + UpdateFeaturesCache(ReadCampaignFeatures(campaignData)); + CreateLocalAdsMarks(std::move(campaignData)); +} + LocalAdsManager::CampaignData LocalAdsManager::ParseCampaign(std::vector const & rawData, MwmSet::MwmId const & mwmId, Timestamp timestamp, @@ -652,12 +659,12 @@ LocalAdsManager::CampaignData LocalAdsManager::ParseCampaign(std::vectorGetEditSession(); for (auto const & data : campaignData) { @@ -673,11 +680,11 @@ void LocalAdsManager::CreateLocalAdsMarks(CampaignData && campaignData) void LocalAdsManager::DeleteLocalAdsMarks(MwmSet::MwmId const & mwmId) { - if (m_bmManager == nullptr) - return; - GetPlatform().RunTask(Platform::Thread::Gui, [this, mwmId]() { + if (m_bmManager == nullptr) + return; + m_bmManager->GetEditSession().DeleteUserMarks(UserMark::Type::LOCAL_ADS, [&mwmId](LocalAdsMark const * mark) { @@ -688,11 +695,11 @@ void LocalAdsManager::DeleteLocalAdsMarks(MwmSet::MwmId const & mwmId) void LocalAdsManager::DeleteAllLocalAdsMarks() { - if (m_bmManager == nullptr) - return; - GetPlatform().RunTask(Platform::Thread::Gui, [this]() { + if (m_bmManager == nullptr) + return; + m_bmManager->GetEditSession().ClearGroup(UserMark::Type::LOCAL_ADS); }); } @@ -830,6 +837,9 @@ void LocalAdsManager::OnLocationUpdate(location::GpsInfo const & info, int zoomL if (!m_isEnabled) return; + if (info.m_horizontalAccuracy > kMaxAllowableAccuracyInMeters) + return; + if (std::chrono::steady_clock::now() < (m_lastCheckTime + kMinCheckInterval)) return; diff --git a/map/local_ads_manager.hpp b/map/local_ads_manager.hpp index 7d6b6aee37..efbc6dd559 100644 --- a/map/local_ads_manager.hpp +++ b/map/local_ads_manager.hpp @@ -104,6 +104,8 @@ private: void Start(); + void InvalidateImpl(); + void ProcessRequests(std::set && campaignMwms); void ReadCampaignFile(std::string const & campaignFile);