From 04f1374eb7a71b5e14a226d2559ce5f3760403f8 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Tue, 10 Apr 2018 16:42:01 +0300 Subject: [PATCH] Reset bookmark ids in case when the persistent id storage is reseted or when a foreign kmb file detected. --- kml/types.hpp | 2 + map/bookmark_helpers.cpp | 9 ++++ map/bookmark_helpers.hpp | 2 + map/bookmark_manager.cpp | 22 +++++++--- map/map_tests/kmz_unarchive_test.cpp | 2 +- map/track.cpp | 2 +- map/user_mark.cpp | 6 +-- map/user_mark_id_storage.cpp | 64 +++++++++++++++++++--------- map/user_mark_id_storage.hpp | 12 ++++-- 9 files changed, 85 insertions(+), 36 deletions(-) diff --git a/kml/types.hpp b/kml/types.hpp index 187bb9964f..0406513862 100644 --- a/kml/types.hpp +++ b/kml/types.hpp @@ -297,6 +297,8 @@ struct FileData bool operator!=(FileData const & data) const { return !operator==(data); } + // Device id. + std::string m_deviceId; // Category's data. CategoryData m_categoryData; // Bookmarks collection. diff --git a/map/bookmark_helpers.cpp b/map/bookmark_helpers.cpp index bac3643877..69dd83c903 100644 --- a/map/bookmark_helpers.cpp +++ b/map/bookmark_helpers.cpp @@ -108,6 +108,15 @@ bool SaveKmlData(kml::FileData & kmlData, Writer & writer, bool useBinary) return true; } +void ResetIds(kml::FileData & kmlData) +{ + kmlData.m_categoryData.m_id = kml::kInvalidMarkGroupId; + for (auto & bmData : kmlData.m_bookmarksData) + bmData.m_id = kml::kInvalidMarkId; + for (auto & trackData : kmlData.m_tracksData) + trackData.m_id = kml::kInvalidTrackId; +} + void SaveFeatureInfo(StringUtf8Multilang const & name, feature::TypesHolder const & types, kml::BookmarkData & bmData) { bmData.m_featureTypes.assign(types.begin(), types.end()); diff --git a/map/bookmark_helpers.hpp b/map/bookmark_helpers.hpp index 5e42109d8f..f2b63ca3c8 100644 --- a/map/bookmark_helpers.hpp +++ b/map/bookmark_helpers.hpp @@ -15,5 +15,7 @@ std::unique_ptr LoadKmlData(Reader const & reader, bool useBinary bool SaveKmlFile(kml::FileData & kmlData, std::string const & file, bool useBinary); bool SaveKmlData(kml::FileData & kmlData, Writer & writer, bool useBinary); +void ResetIds(kml::FileData & kmlData); + void SaveFeatureInfo(StringUtf8Multilang const & name, feature::TypesHolder const & types, kml::BookmarkData & bmData); diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 1dc6f94358..e1a9c0d5ba 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -944,17 +944,17 @@ void BookmarkManager::NotifyAboutFinishAsyncLoading(KMLDataCollectionPtr && coll GetPlatform().RunTask(Platform::Thread::Gui, [this, collection]() { - m_asyncLoadingInProgress = false; - m_loadBookmarksFinished = true; if (!collection->empty()) { CreateCategories(std::move(*collection)); } - else + else if (!m_loadBookmarksFinished) { CheckAndResetLastIds(); CheckAndCreateDefaultCategory(); } + m_asyncLoadingInProgress = false; + m_loadBookmarksFinished = true; if (m_asyncLoadingCallbacks.m_onFinished != nullptr) m_asyncLoadingCallbacks.m_onFinished(); @@ -1175,7 +1175,7 @@ kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(kml::CategoryData && da if (data.m_id == kml::kInvalidMarkGroupId) { - data.m_id = PersistentIdStorage::Instance().GetNextCategoryId(); + data.m_id = UserMarkIdStorage::Instance().GetNextCategoryId(); } auto groupId = data.m_id; ASSERT_EQUAL(m_categories.count(groupId), 0, ()); @@ -1188,7 +1188,7 @@ kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(kml::CategoryData && da kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(std::string const & name, bool autoSave) { ASSERT_THREAD_CHECKER(m_threadChecker, ()); - auto const groupId = PersistentIdStorage::Instance().GetNextCategoryId(); + auto const groupId = UserMarkIdStorage::Instance().GetNextCategoryId(); m_categories[groupId] = my::make_unique(name, groupId, autoSave); UpdateBmGroupIdList(); m_changesTracker.OnAddGroup(groupId); @@ -1204,7 +1204,7 @@ void BookmarkManager::CheckAndCreateDefaultCategory() void BookmarkManager::CheckAndResetLastIds() { - auto & idStorage = PersistentIdStorage::Instance(); + auto & idStorage = UserMarkIdStorage::Instance(); if (m_categories.empty()) idStorage.ResetCategoryId(); if (m_bookmarks.empty()) @@ -1313,6 +1313,12 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool auto & fileData = *data.second.get(); auto & categoryData = fileData.m_categoryData; + if ((categoryData.m_id != kml::kInvalidMarkGroupId) && + (UserMarkIdStorage::Instance().IsJustCreated() || fileData.m_deviceId != GetPlatform().UniqueClientId())) + { + ResetIds(fileData); + } + auto const originalName = kml::GetDefaultStr(categoryData.m_name); auto uniqueName = originalName; @@ -1362,6 +1368,7 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool std::unique_ptr BookmarkManager::CollectBmGroupKMLData(BookmarkCategory const * group) const { auto kmlData = std::make_unique(); + kmlData->m_deviceId = GetPlatform().UniqueClientId(); kmlData->m_categoryData = group->GetCategoryData(); auto const & markIds = group->GetUserMarks(); kmlData->m_bookmarksData.reserve(markIds.size()); @@ -1692,6 +1699,7 @@ void BookmarkManager::OnRestoredFilesPrepared() { // This method is always called from UI-thread. ClearCategories(); + CheckAndResetLastIds(); if (m_onRestoredFilesPrepared) m_onRestoredFilesPrepared(); @@ -1716,7 +1724,7 @@ void BookmarkManager::CancelCloudRestoring() void BookmarkManager::EnableTestMode(bool enable) { - PersistentIdStorage::Instance().EnableTestMode(enable); + UserMarkIdStorage::Instance().EnableTestMode(enable); m_testModeEnabled = enable; } diff --git a/map/map_tests/kmz_unarchive_test.cpp b/map/map_tests/kmz_unarchive_test.cpp index 60b3d5842c..3d5f424ecd 100644 --- a/map/map_tests/kmz_unarchive_test.cpp +++ b/map/map_tests/kmz_unarchive_test.cpp @@ -17,7 +17,7 @@ UNIT_TEST(KMZ_UnzipTest) { - PersistentIdStorage::Instance().EnableTestMode(true); + UserMarkIdStorage::Instance().EnableTestMode(true); string const kmzFile = GetPlatform().TestsDataPathForFile("test.kmz"); ZipFileReader::FileListT files; diff --git a/map/track.cpp b/map/track.cpp index 9f0ad61bf5..1c70e7a394 100644 --- a/map/track.cpp +++ b/map/track.cpp @@ -5,7 +5,7 @@ #include "geometry/mercator.hpp" Track::Track(kml::TrackData && data) - : Base(data.m_id == kml::kInvalidTrackId ? PersistentIdStorage::Instance().GetNextTrackId() : data.m_id) + : Base(data.m_id == kml::kInvalidTrackId ? UserMarkIdStorage::Instance().GetNextTrackId() : data.m_id) , m_data(std::move(data)) , m_groupID(0) { diff --git a/map/user_mark.cpp b/map/user_mark.cpp index 85c2105aa0..3e3037a962 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -4,21 +4,21 @@ #include "geometry/mercator.hpp" UserMark::UserMark(kml::MarkId id, m2::PointD const & ptOrg, UserMark::Type type) - : df::UserPointMark(id == kml::kInvalidMarkId ? PersistentIdStorage::Instance().GetNextUserMarkId(type) : id) + : df::UserPointMark(id == kml::kInvalidMarkId ? UserMarkIdStorage::Instance().GetNextUserMarkId(type) : id) , m_ptOrg(ptOrg) { ASSERT_EQUAL(GetMarkType(), type, ()); } UserMark::UserMark(m2::PointD const & ptOrg, UserMark::Type type) - : df::UserPointMark(PersistentIdStorage::Instance().GetNextUserMarkId(type)) + : df::UserPointMark(UserMarkIdStorage::Instance().GetNextUserMarkId(type)) , m_ptOrg(ptOrg) {} // static UserMark::Type UserMark::GetMarkType(kml::MarkId id) { - return PersistentIdStorage::GetMarkType(id); + return UserMarkIdStorage::GetMarkType(id); } m2::PointD const & UserMark::GetPivot() const diff --git a/map/user_mark_id_storage.cpp b/map/user_mark_id_storage.cpp index 5660f664b2..9a344c7b66 100644 --- a/map/user_mark_id_storage.cpp +++ b/map/user_mark_id_storage.cpp @@ -12,46 +12,62 @@ std::string const kLastTrackId = "LastTrackId"; std::string const kLastBookmarkCategoryId = "LastBookmarkCategoryId"; } // namespace -PersistentIdStorage::PersistentIdStorage() - : m_lastUserMarkId(0) +UserMarkIdStorage::UserMarkIdStorage() + : m_isJustCreated(false) + , m_lastUserMarkId(0) { - LoadLastBookmarkId(); - LoadLastTrackId(); - LoadLastCategoryId(); + m_isJustCreated = !(HasKey(kLastBookmarkCategoryId) && HasKey(kLastBookmarkId) && HasKey(kLastTrackId)); + if (m_isJustCreated) + { + ResetCategoryId(); + ResetBookmarkId(); + ResetTrackId(); + } + else + { + LoadLastBookmarkId(); + LoadLastTrackId(); + LoadLastCategoryId(); + } } // static -PersistentIdStorage & PersistentIdStorage::Instance() +UserMarkIdStorage & UserMarkIdStorage::Instance() { - static PersistentIdStorage instance; + static UserMarkIdStorage instance; return instance; } // static -UserMark::Type PersistentIdStorage::GetMarkType(kml::MarkId id) +UserMark::Type UserMarkIdStorage::GetMarkType(kml::MarkId id) { return static_cast(id >> (sizeof(id) * 8 - kMarkIdTypeBitsCount)); } -void PersistentIdStorage::ResetBookmarkId() +bool UserMarkIdStorage::IsJustCreated() const +{ + return m_isJustCreated; +} + +void UserMarkIdStorage::ResetBookmarkId() { m_lastBookmarkId = 0; SaveLastBookmarkId(); } -void PersistentIdStorage::ResetTrackId() +void UserMarkIdStorage::ResetTrackId() { m_lastTrackId = 0; SaveLastTrackId(); } -void PersistentIdStorage::ResetCategoryId() +void UserMarkIdStorage::ResetCategoryId() { m_lastCategoryId = static_cast(UserMark::Type::USER_MARK_TYPES_COUNT_MAX); SaveLastCategoryId(); } -kml::MarkId PersistentIdStorage::GetNextUserMarkId(UserMark::Type type) +kml::MarkId UserMarkIdStorage::GetNextUserMarkId(UserMark::Type type) { static_assert(UserMark::Type::USER_MARK_TYPES_COUNT <= (1 << kMarkIdTypeBitsCount), "Not enough bits for user mark type."); @@ -69,21 +85,27 @@ kml::MarkId PersistentIdStorage::GetNextUserMarkId(UserMark::Type type) } } -kml::TrackId PersistentIdStorage::GetNextTrackId() +kml::TrackId UserMarkIdStorage::GetNextTrackId() { auto const id = static_cast(++m_lastTrackId); SaveLastTrackId(); return id; } -kml::MarkGroupId PersistentIdStorage::GetNextCategoryId() +kml::MarkGroupId UserMarkIdStorage::GetNextCategoryId() { auto const id = static_cast(++m_lastCategoryId); SaveLastCategoryId(); return id; } -void PersistentIdStorage::LoadLastBookmarkId() +bool UserMarkIdStorage::HasKey(std::string const & name) +{ + std::string val; + return GetPlatform().GetSecureStorage().Load(name, val); +} + +void UserMarkIdStorage::LoadLastBookmarkId() { uint64_t lastId; std::string val; @@ -93,7 +115,7 @@ void PersistentIdStorage::LoadLastBookmarkId() m_lastBookmarkId = 0; } -void PersistentIdStorage::LoadLastTrackId() +void UserMarkIdStorage::LoadLastTrackId() { uint64_t lastId; std::string val; @@ -103,7 +125,7 @@ void PersistentIdStorage::LoadLastTrackId() m_lastTrackId = 0; } -void PersistentIdStorage::LoadLastCategoryId() +void UserMarkIdStorage::LoadLastCategoryId() { uint64_t lastId; std::string val; @@ -113,28 +135,28 @@ void PersistentIdStorage::LoadLastCategoryId() m_lastCategoryId = static_cast(UserMark::USER_MARK_TYPES_COUNT_MAX); } -void PersistentIdStorage::SaveLastBookmarkId() +void UserMarkIdStorage::SaveLastBookmarkId() { if (m_testModeEnabled) return; GetPlatform().GetSecureStorage().Save(kLastBookmarkId, strings::to_string(m_lastBookmarkId.load())); } -void PersistentIdStorage::SaveLastTrackId() +void UserMarkIdStorage::SaveLastTrackId() { if (m_testModeEnabled) return; GetPlatform().GetSecureStorage().Save(kLastTrackId, strings::to_string(m_lastTrackId.load())); } -void PersistentIdStorage::SaveLastCategoryId() +void UserMarkIdStorage::SaveLastCategoryId() { if (m_testModeEnabled) return; GetPlatform().GetSecureStorage().Save(kLastBookmarkCategoryId, strings::to_string(m_lastCategoryId.load())); } -void PersistentIdStorage::EnableTestMode(bool enable) +void UserMarkIdStorage::EnableTestMode(bool enable) { m_testModeEnabled = enable; } diff --git a/map/user_mark_id_storage.hpp b/map/user_mark_id_storage.hpp index f52ed55e55..c23457b99f 100644 --- a/map/user_mark_id_storage.hpp +++ b/map/user_mark_id_storage.hpp @@ -4,13 +4,15 @@ #include -class PersistentIdStorage +class UserMarkIdStorage { public: - static PersistentIdStorage & Instance(); + static UserMarkIdStorage & Instance(); static UserMark::Type GetMarkType(kml::MarkId id); + bool IsJustCreated() const; + kml::MarkId GetNextUserMarkId(UserMark::Type type); kml::TrackId GetNextTrackId(); kml::MarkGroupId GetNextCategoryId(); @@ -23,7 +25,7 @@ public: void EnableTestMode(bool enable); private: - PersistentIdStorage(); + UserMarkIdStorage(); void LoadLastBookmarkId(); void LoadLastTrackId(); @@ -33,6 +35,10 @@ private: void SaveLastTrackId(); void SaveLastCategoryId(); + bool HasKey(std::string const & name); + + std::atomic m_isJustCreated; + std::atomic m_lastBookmarkId; std::atomic m_lastTrackId; std::atomic m_lastUserMarkId;