diff --git a/android/jni/com/mapswithme/maps/LocationHelper.cpp b/android/jni/com/mapswithme/maps/LocationHelper.cpp index 973eff5a71..bdc6a3cd9f 100644 --- a/android/jni/com/mapswithme/maps/LocationHelper.cpp +++ b/android/jni/com/mapswithme/maps/LocationHelper.cpp @@ -1,5 +1,5 @@ #include "Framework.hpp" -#include "map/gps_track.hpp" +#include "map/gps_tracker.hpp" #include "platform/file_logging.hpp" extern "C" @@ -40,8 +40,7 @@ extern "C" LOG_MEMORY_INFO(); if (g_framework) g_framework->OnLocationUpdated(info); - else - GetDefaultGpsTrack().AddPoint(info); + GpsTracker::Instance().OnLocationUpdated(info); } JNIEXPORT jfloatArray JNICALL diff --git a/android/jni/com/mapswithme/maps/TrackRecorder.cpp b/android/jni/com/mapswithme/maps/TrackRecorder.cpp index 500857bee3..c21dd0850e 100644 --- a/android/jni/com/mapswithme/maps/TrackRecorder.cpp +++ b/android/jni/com/mapswithme/maps/TrackRecorder.cpp @@ -1,5 +1,7 @@ #include "Framework.hpp" +#include "map/gps_tracker.hpp" + #include "std/chrono.hpp" namespace @@ -7,7 +9,6 @@ namespace ::Framework * frm() { - // TODO (trashkalmar): Temp solution until the GPS tracker is uncoupled from the framework. return (g_framework ? g_framework->NativeFramework() : nullptr); } @@ -18,49 +19,31 @@ extern "C" JNIEXPORT void JNICALL Java_com_mapswithme_maps_location_TrackRecorder_nativeSetEnabled(JNIEnv * env, jclass clazz, jboolean enable) { - // TODO (trashkalmar): Temp solution until the GPS tracker is uncoupled from the framework. - - ::Framework * const framework = frm(); - if (framework) - { - framework->EnableGpsTracking(enable); + GpsTracker::Instance().SetEnabled(enable); + Framework * const f = frm(); + if (f == nullptr) return; - } - - Settings::Set("GpsTrackingEnabled", static_cast(enable)); + if (enable) + f->ConnectToGpsTracker(); + else + f->DisconnectFromGpsTracker(); } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_location_TrackRecorder_nativeIsEnabled(JNIEnv * env, jclass clazz) { - // TODO (trashkalmar): Temp solution until the GPS tracker is uncoupled from the framework. - - ::Framework * const framework = frm(); - if (framework) - return framework->IsGpsTrackingEnabled(); - - bool res = false; - Settings::Get("GpsTrackingEnabled", res); - return res; + return GpsTracker::Instance().IsEnabled(); } JNIEXPORT void JNICALL Java_com_mapswithme_maps_location_TrackRecorder_nativeSetDuration(JNIEnv * env, jclass clazz, jint durationHours) { - frm()->SetGpsTrackingDuration(hours(durationHours)); + return GpsTracker::Instance().SetDuration(hours(durationHours)); } JNIEXPORT jint JNICALL Java_com_mapswithme_maps_location_TrackRecorder_nativeGetDuration(JNIEnv * env, jclass clazz) { - // TODO (trashkalmar): Temp solution until the GPS tracker is uncoupled from the framework. - - ::Framework * const framework = frm(); - if (framework) - return framework->GetGpsTrackingDuration().count(); - - uint32_t res = 24; - Settings::Get("GpsTrackingDuration", res); - return res; + return GpsTracker::Instance().GetDuration().count(); } } diff --git a/iphone/Maps/MWMRecentTrackSettingsController.mm b/iphone/Maps/MWMRecentTrackSettingsController.mm index d0566a5187..a21224ba6a 100644 --- a/iphone/Maps/MWMRecentTrackSettingsController.mm +++ b/iphone/Maps/MWMRecentTrackSettingsController.mm @@ -3,6 +3,8 @@ #include "Framework.h" +#include "map/gps_tracker.hpp" + typedef NS_ENUM(NSUInteger, DurationInHours) { One = 1, @@ -30,15 +32,14 @@ typedef NS_ENUM(NSUInteger, DurationInHours) { [super viewDidLoad]; self.title = L(@"recent_track"); - auto & f = GetFramework(); - if (!f.IsGpsTrackingEnabled()) + if (!GpsTracker::Instance().IsEnabled()) { _selectedCell = self.none; } else { - switch (f.GetGpsTrackingDuration().count()) + switch (GpsTracker::Instance().GetDuration().count()) { case One: _selectedCell = self.oneHour; @@ -68,22 +69,25 @@ typedef NS_ENUM(NSUInteger, DurationInHours) _selectedCell = selectedCell; auto & f = GetFramework(); if ([selectedCell isEqual:self.none]) - f.EnableGpsTracking(false); + { + f.DisconnectFromGpsTracker(); + GpsTracker::Instance().SetEnabled(false); + } else { - if (!f.IsGpsTrackingEnabled()) - f.EnableGpsTracking(true); + GpsTracker::Instance().SetEnabled(true); + f.ConnectToGpsTracker(); if ([selectedCell isEqual:self.oneHour]) - f.SetGpsTrackingDuration(hours(One)); + GpsTracker::Instance().SetDuration(hours(One)); else if ([selectedCell isEqual:self.twoHours]) - f.SetGpsTrackingDuration(hours(Two)); + GpsTracker::Instance().SetDuration(hours(Two)); else if ([selectedCell isEqual:self.sixHours]) - f.SetGpsTrackingDuration(hours(Six)); + GpsTracker::Instance().SetDuration(hours(Six)); else if ([selectedCell isEqual:self.twelveHours]) - f.SetGpsTrackingDuration(hours(Twelve)); + GpsTracker::Instance().SetDuration(hours(Twelve)); else - f.SetGpsTrackingDuration(hours(Day)); + GpsTracker::Instance().SetDuration(hours(Day)); } selectedCell.accessoryType = UITableViewCellAccessoryCheckmark; } diff --git a/iphone/Maps/Platform/LocationManager.mm b/iphone/Maps/Platform/LocationManager.mm index 74f7401878..65bccf11cf 100644 --- a/iphone/Maps/Platform/LocationManager.mm +++ b/iphone/Maps/Platform/LocationManager.mm @@ -9,7 +9,7 @@ #include "Framework.h" -#include "map/gps_track.hpp" +#include "map/gps_tracker.hpp" #include "platform/measurement_utils.hpp" #include "platform/settings.hpp" #include "base/math.hpp" @@ -74,7 +74,7 @@ static NSString * const kAlohalyticsLocationRequestAlwaysFailed = @"$locationAlw - (void)beforeTerminate { - if (GetFramework().IsGpsTrackingEnabled()) + if (GpsTracker::Instance().IsEnabled()) [m_locationManager startMonitoringSignificantLocationChanges]; } @@ -184,16 +184,13 @@ static NSString * const kAlohalyticsLocationRequestAlwaysFailed = @"$locationAlw m_lastLocationTime = [NSDate date]; [[Statistics instance] logLocation:location]; auto const newInfo = gpsInfoFromLocation(location); - if (self.isDaemonMode) - { - GetDefaultGpsTrack().AddPoint(newInfo); - } - else + if (!self.isDaemonMode) { for (id observer in m_observers) [observer onLocationUpdate:newInfo]; // TODO(AlexZ): Temporary, remove in the future. } + GpsTracker::Instance().OnLocationUpdated(newInfo); } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error diff --git a/map/framework.cpp b/map/framework.cpp index 5cf998eb21..42c953bba5 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -2,6 +2,7 @@ #include "map/ge0_parser.hpp" #include "map/geourl_process.hpp" +#include "map/gps_tracker.hpp" #include "map/storage_bridge.hpp" #include "defines.hpp" @@ -94,9 +95,6 @@ namespace char const kRouterTypeKey[] = "router"; char const kMapStyleKey[] = "MapStyleKeyV1"; - char const kGpsTrackingEnabledKey[] = "GpsTrackingEnabled"; - char const kGpsTrackingDurationHours[] = "GpsTrackingDuration"; - uint32_t const kDefaultGpsTrackingMaxDurationHours = 24; char const kAllow3dKey[] = "Allow3d"; char const kAllow3dBuildingsKey[] = "Buildings3d"; @@ -147,9 +145,6 @@ void Framework::OnLocationUpdate(GpsInfo const & info) CallDrapeFunction(bind(&df::DrapeEngine::SetGpsInfo, _1, rInfo, m_routingSession.IsNavigable(), routeMatchingInfo)); - - if (m_gpsTrackingEnabled) - m_gpsTrack.AddPoint(info); } void Framework::OnCompassUpdate(CompassInfo const & info) @@ -201,8 +196,6 @@ void Framework::StopLocationFollow() Framework::Framework() : m_bmManager(*this) - , m_gpsTrackingEnabled(false) - , m_gpsTrack(GetDefaultGpsTrack()) , m_fixedSearchResults(0) { m_activeMaps.reset(new ActiveMapsLayout(*this)); @@ -215,15 +208,7 @@ Framework::Framework() mapStyle = MapStyleClear; GetStyleReader().SetCurrentStyle(static_cast(mapStyle)); - // Restore gps tracking enabled - bool gpsTrackingEnabled = false; - Settings::Get(kGpsTrackingEnabledKey, gpsTrackingEnabled); - m_gpsTrackingEnabled = gpsTrackingEnabled; - - // Restore gps tracking duration, hours - uint32_t duration = kDefaultGpsTrackingMaxDurationHours; - Settings::Get(kGpsTrackingDurationHours, duration); - m_gpsTrack.SetDuration(hours(duration)); + m_connectToGpsTrack = GpsTracker::Instance().IsEnabled(); m_ParsedMapApi.SetBookmarkManager(&m_bmManager); @@ -1318,8 +1303,11 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, m_drapeEngine->EnablePerspective(kRotationAngle, kAngleFOV); } - if (m_gpsTrackingEnabled) - m_gpsTrack.SetCallback(bind(&Framework::OnUpdateGpsTrackPointsCallback, this, _1, _2)); + if (m_connectToGpsTrack) + { + m_connectToGpsTrack = false; + GpsTracker::Instance().Connect(bind(&Framework::OnUpdateGpsTrackPointsCallback, this, _1, _2)); + } } ref_ptr Framework::GetDrapeEngine() @@ -1329,59 +1317,30 @@ ref_ptr Framework::GetDrapeEngine() void Framework::DestroyDrapeEngine() { - m_gpsTrack.SetCallback(nullptr); - + GpsTracker::Instance().Disconnect(); m_drapeEngine.reset(); } -void Framework::EnableGpsTracking(bool enabled) +void Framework::ConnectToGpsTracker() { - // NOTE! - // In future we will distinguish GPS tracking and visualization of GPS tracking (for example, we could - // track a position, but render it only if user asks to render track). - // For now, GPS tracking and visualization of GPS tracking are treated as the same. - - if (enabled == m_gpsTrackingEnabled) - return; - - m_gpsTrackingEnabled = enabled; - - Settings::Set(kGpsTrackingEnabledKey, enabled); - - if (enabled) + if (m_drapeEngine) { - m_gpsTrack.Clear(); - - if (m_drapeEngine) - m_gpsTrack.SetCallback(bind(&Framework::OnUpdateGpsTrackPointsCallback, this, _1, _2)); + m_connectToGpsTrack = false; + m_drapeEngine->ClearGpsTrackPoints(); + GpsTracker::Instance().Connect(bind(&Framework::OnUpdateGpsTrackPointsCallback, this, _1, _2)); } else { - // Reset callback first to prevent notification about removed points on Clear - m_gpsTrack.SetCallback(nullptr); - m_gpsTrack.Clear(); - - if (m_drapeEngine) - m_drapeEngine->ClearGpsTrackPoints(); + // Postspone connect to tracker until is being constructed + m_connectToGpsTrack = true; } } -bool Framework::IsGpsTrackingEnabled() const +void Framework::DisconnectFromGpsTracker() { - return m_gpsTrackingEnabled; -} - -void Framework::SetGpsTrackingDuration(hours duration) -{ - uint32_t const hours = duration.count(); - Settings::Set(kGpsTrackingDurationHours, hours); - - m_gpsTrack.SetDuration(duration); -} - -hours Framework::GetGpsTrackingDuration() const -{ - return m_gpsTrack.GetDuration(); + m_connectToGpsTrack = false; + m_drapeEngine->ClearGpsTrackPoints(); + GpsTracker::Instance().Disconnect(); } void Framework::OnUpdateGpsTrackPointsCallback(vector> && toAdd, diff --git a/map/framework.hpp b/map/framework.hpp index 77e96eb1fb..5bb45a988d 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -6,7 +6,6 @@ #include "map/bookmark_manager.hpp" #include "map/country_tree.hpp" #include "map/feature_vec_model.hpp" -#include "map/gps_track.hpp" #include "map/mwm_url.hpp" #include "map/track.hpp" @@ -38,7 +37,6 @@ #include "base/strings_bundle.hpp" #include "base/thread_checker.hpp" -#include "std/atomic.hpp" #include "std/list.hpp" #include "std/shared_ptr.hpp" #include "std/target_os.hpp" @@ -129,9 +127,6 @@ protected: BookmarkManager m_bmManager; - atomic m_gpsTrackingEnabled; - GpsTrack & m_gpsTrack; - /// This function is called by m_storage when latest local files /// were changed. void UpdateLatestCountryFile(platform::LocalCountryFile const & localFile); @@ -319,10 +314,8 @@ public: ref_ptr GetDrapeEngine(); void DestroyDrapeEngine(); - void EnableGpsTracking(bool enabled); - bool IsGpsTrackingEnabled() const; - void SetGpsTrackingDuration(hours duration); - hours GetGpsTrackingDuration() const; + void ConnectToGpsTracker(); + void DisconnectFromGpsTracker(); void SetMapStyle(MapStyle mapStyle); MapStyle GetMapStyle() const; @@ -341,6 +334,8 @@ private: search::SearchParams m_lastSearch; uint8_t m_fixedSearchResults; + bool m_connectToGpsTrack; // need to connect to tracker when Drape is being constructed + void FillSearchResultsMarks(search::Results const & results); void OnDownloadMapCallback(storage::TIndex const & countryIndex); @@ -501,7 +496,7 @@ public: //@} public: - using TRouteBuildingCallback = function const &, vector const &)>; using TRouteProgressCallback = function; diff --git a/map/gps_track.cpp b/map/gps_track.cpp index 34460f933e..75eadd11b4 100644 --- a/map/gps_track.cpp +++ b/map/gps_track.cpp @@ -1,20 +1,11 @@ #include "map/gps_track.hpp" -#include "coding/file_name_utils.hpp" - -#include "platform/platform.hpp" - #include "base/assert.hpp" #include "base/logging.hpp" -#include "defines.hpp" - namespace { -size_t const kMaxItemCount = 100000; -hours const kDefaultDuration = hours(24); - inline pair UnionRanges(pair const & a, pair const & b) { if (a.first == GpsTrack::kInvalidId) @@ -320,9 +311,3 @@ void GpsTrack::NotifyCallback(pair const & addedIds, pair 24h with 1point/s + +inline string GetFilePath() +{ + return my::JoinFoldersToPath(GetPlatform().WritableDir(), GPS_TRACK_FILENAME); +} + +inline bool GetSettingsIsEnabled() +{ + bool enabled = false; + Settings::Get(kEnabledKey, enabled); + return enabled; +} + +inline void SetSettingsIsEnabled(bool enabled) +{ + Settings::Set(kEnabledKey, enabled); +} + +inline hours GetSettingsDuration() +{ + uint32_t duration = kDefaultDurationHours; + Settings::Get(kDurationHours, duration); + return hours(duration); +} + +inline void SetSettingsDuration(hours duration) +{ + uint32_t const hours = duration.count(); + Settings::Set(kDurationHours, hours); +} + +} // namespace + +GpsTracker & GpsTracker::Instance() +{ + static GpsTracker instance; + return instance; +} + +GpsTracker::GpsTracker() + : m_enabled(GetSettingsIsEnabled()) + , m_duration(GetSettingsDuration()) + , m_track(GetFilePath(), kMaxItemCount, m_duration) +{ +} + +void GpsTracker::SetEnabled(bool enabled) +{ + if (enabled == m_enabled) + return; + + SetSettingsIsEnabled(enabled); + m_enabled = enabled; + + if (enabled) + m_track.Clear(); +} + +bool GpsTracker::IsEnabled() const +{ + return m_enabled; +} + +void GpsTracker::SetDuration(hours duration) +{ + SetSettingsDuration(duration); + m_duration = duration; +} + +hours GpsTracker::GetDuration() const +{ + return m_duration; +} + +void GpsTracker::Connect(TGpsTrackDiffCallback const & fn) +{ + m_track.SetCallback(fn); +} + +void GpsTracker::Disconnect() +{ + m_track.SetCallback(nullptr); +} + +void GpsTracker::OnLocationUpdated(location::GpsInfo const & info) +{ + if (!m_enabled) + return; + m_track.AddPoint(info); +} diff --git a/map/gps_tracker.hpp b/map/gps_tracker.hpp new file mode 100644 index 0000000000..6832e57d89 --- /dev/null +++ b/map/gps_tracker.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "map/gps_track.hpp" + +#include "std/atomic.hpp" + +class GpsTracker +{ +public: + static GpsTracker & Instance(); + + bool IsEnabled() const; + void SetEnabled(bool enabled); + + hours GetDuration() const; + void SetDuration(hours duration); + + using TGpsTrackDiffCallback = std::function> && toAdd, + pair const & toRemove)>; + + void Connect(TGpsTrackDiffCallback const & fn); + void Disconnect(); + + void OnLocationUpdated(location::GpsInfo const & info); + +private: + GpsTracker(); + + atomic m_enabled; + hours m_duration; + GpsTrack m_track; +}; diff --git a/map/map.pro b/map/map.pro index 21d5a35229..ab4634cb8a 100644 --- a/map/map.pro +++ b/map/map.pro @@ -25,6 +25,7 @@ HEADERS += \ gps_track_collection.hpp \ gps_track_filter.hpp \ gps_track_storage.hpp \ + gps_tracker.hpp \ mwm_url.hpp \ storage_bridge.hpp \ styled_point.hpp \ @@ -48,6 +49,7 @@ SOURCES += \ gps_track_filter.cpp \ gps_track_collection.cpp \ gps_track_storage.cpp \ + gps_tracker.cpp \ mwm_url.cpp \ storage_bridge.cpp \ styled_point.cpp \