|
6 | 6 | #include "brave/components/brave_sync/brave_profile_sync_service_impl.h"
|
7 | 7 |
|
8 | 8 | #include <algorithm>
|
| 9 | +#include <map> |
9 | 10 | #include <utility>
|
10 | 11 | #include <vector>
|
11 | 12 |
|
@@ -165,6 +166,57 @@ SyncRecordPtr PrepareResolvedDevice(SyncDevice* device,
|
165 | 166 | record->SetDevice(std::move(device_record));
|
166 | 167 | return record;
|
167 | 168 | }
|
| 169 | + |
| 170 | +struct BookmarkByDateAddedComparator { |
| 171 | + bool operator()(const bookmarks::BookmarkNode* lhs, |
| 172 | + const bookmarks::BookmarkNode* rhs) const { |
| 173 | + DCHECK(lhs); |
| 174 | + DCHECK(rhs); |
| 175 | + DCHECK(!tools::IsTimeEmpty(lhs->date_added())); |
| 176 | + DCHECK(!tools::IsTimeEmpty(rhs->date_added())); |
| 177 | + return lhs->date_added() < rhs->date_added(); |
| 178 | + } |
| 179 | +}; |
| 180 | +using SortedNodes = |
| 181 | + std::set<const bookmarks::BookmarkNode*, BookmarkByDateAddedComparator>; |
| 182 | +using ObjectIdToNodes = std::map<std::string, SortedNodes>; |
| 183 | + |
| 184 | +void FillObjectsMap(const bookmarks::BookmarkNode* parent, |
| 185 | + ObjectIdToNodes* object_id_nodes) { |
| 186 | + for (size_t i = 0; i < parent->children().size(); ++i) { |
| 187 | + const bookmarks::BookmarkNode* current_child = parent->children()[i].get(); |
| 188 | + std::string object_id; |
| 189 | + if (current_child->GetMetaInfo("object_id", &object_id) && |
| 190 | + !object_id.empty()) { |
| 191 | + (*object_id_nodes)[object_id].insert(current_child); |
| 192 | + } |
| 193 | + if (current_child->is_folder()) { |
| 194 | + FillObjectsMap(current_child, object_id_nodes); |
| 195 | + } |
| 196 | + } |
| 197 | +} |
| 198 | + |
| 199 | +void ClearDuplicatedNodes(ObjectIdToNodes* object_id_nodes, |
| 200 | + bookmarks::BookmarkModel* model) { |
| 201 | + for (ObjectIdToNodes::iterator it_object_id = object_id_nodes->begin(); |
| 202 | + it_object_id != object_id_nodes->end(); ++it_object_id) { |
| 203 | + const SortedNodes& nodes = it_object_id->second; |
| 204 | + if (nodes.size() > 1) { |
| 205 | + // Nodes are sorted from oldest to newest, go to the second by age |
| 206 | + SortedNodes::iterator it_nodes = nodes.begin(); |
| 207 | + ++it_nodes; |
| 208 | + for (; it_nodes != nodes.end(); ++it_nodes) { |
| 209 | + const bookmarks::BookmarkNode* node = *it_nodes; |
| 210 | + // Copy and delete node |
| 211 | + const auto* parent = node->parent(); |
| 212 | + size_t original_index = parent->GetIndexOf(node); |
| 213 | + model->Copy(node, parent, original_index); |
| 214 | + model->Remove(node); |
| 215 | + brave_sync::AddBraveMetaInfo(parent->children()[original_index].get()); |
| 216 | + } |
| 217 | + } |
| 218 | + } |
| 219 | +} |
168 | 220 | } // namespace
|
169 | 221 |
|
170 | 222 | BraveProfileSyncServiceImpl::BraveProfileSyncServiceImpl(Profile* profile,
|
@@ -755,6 +807,30 @@ void BraveProfileSyncServiceImpl::SetPermanentNodesOrder(
|
755 | 807 | brave_sync_prefs_->SetMigratedBookmarksVersion(2);
|
756 | 808 | }
|
757 | 809 |
|
| 810 | +// static |
| 811 | +void BraveProfileSyncServiceImpl::MigrateDuplicatedBookmarksObjectIds( |
| 812 | + Profile* profile, |
| 813 | + BookmarkModel* model) { |
| 814 | + DCHECK(model); |
| 815 | + DCHECK(model->loaded()); |
| 816 | + |
| 817 | + bool duplicated_bookmarks_recovered = |
| 818 | + profile->GetPrefs()->GetBoolean(prefs::kDuplicatedBookmarksRecovered); |
| 819 | + if (duplicated_bookmarks_recovered) { |
| 820 | + return; |
| 821 | + } |
| 822 | + |
| 823 | + // Copying bookmarks through brave://bookmarks page could duplicate brave sync |
| 824 | + // metadata, which caused crash during chromium sync run |
| 825 | + // Go through nodes and re-create the oldest ones who have duplicated |
| 826 | + // object_id |
| 827 | + ObjectIdToNodes object_id_nodes; |
| 828 | + FillObjectsMap(model->root_node(), &object_id_nodes); |
| 829 | + ClearDuplicatedNodes(&object_id_nodes, model); |
| 830 | + |
| 831 | + profile->GetPrefs()->SetBoolean(prefs::kDuplicatedBookmarksRecovered, true); |
| 832 | +} |
| 833 | + |
758 | 834 | std::unique_ptr<SyncRecord>
|
759 | 835 | BraveProfileSyncServiceImpl::BookmarkNodeToSyncBookmark(
|
760 | 836 | const bookmarks::BookmarkNode* node) {
|
|
0 commit comments