Reset bookmark ids in case when the persistent id storage is reseted or when a foreign kmb file detected.

This commit is contained in:
Daria Volvenkova 2018-04-10 16:42:01 +03:00 committed by Roman Kuznetsov
parent 10a614f428
commit 04f1374eb7
9 changed files with 85 additions and 36 deletions

View file

@ -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.

View file

@ -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());

View file

@ -15,5 +15,7 @@ std::unique_ptr<kml::FileData> 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);

View file

@ -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<BookmarkCategory>(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<kml::FileData> BookmarkManager::CollectBmGroupKMLData(BookmarkCategory const * group) const
{
auto kmlData = std::make_unique<kml::FileData>();
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;
}

View file

@ -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;

View file

@ -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)
{

View file

@ -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

View file

@ -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<UserMark::Type>(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<uint64_t>(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<kml::TrackId>(++m_lastTrackId);
SaveLastTrackId();
return id;
}
kml::MarkGroupId PersistentIdStorage::GetNextCategoryId()
kml::MarkGroupId UserMarkIdStorage::GetNextCategoryId()
{
auto const id = static_cast<kml::TrackId>(++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<uint64_t>(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;
}

View file

@ -4,13 +4,15 @@
#include <atomic>
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<bool> m_isJustCreated;
std::atomic<uint64_t> m_lastBookmarkId;
std::atomic<uint64_t> m_lastTrackId;
std::atomic<uint64_t> m_lastUserMarkId;