blob: c404b8dd99a3bb2928814df2f71d7e4483ec9843 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/sync_bookmarks/bookmark_local_changes_builder.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/strings/utf_string_conversions.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/sync/base/time.h"
#include "components/sync/protocol/bookmark_model_metadata.pb.h"
#include "components/sync_bookmarks/bookmark_specifics_conversions.h"
#include "components/sync_bookmarks/switches.h"
#include "components/sync_bookmarks/synced_bookmark_tracker.h"
#include "components/sync_bookmarks/synced_bookmark_tracker_entity.h"
namespace sync_bookmarks {
BookmarkLocalChangesBuilder::BookmarkLocalChangesBuilder(
SyncedBookmarkTracker* const bookmark_tracker,
bookmarks::BookmarkModel* bookmark_model)
: bookmark_tracker_(bookmark_tracker), bookmark_model_(bookmark_model) {
DCHECK(bookmark_tracker);
DCHECK(bookmark_model);
}
syncer::CommitRequestDataList BookmarkLocalChangesBuilder::BuildCommitRequests(
size_t max_entries) const {
DCHECK(bookmark_tracker_);
const std::vector<const SyncedBookmarkTrackerEntity*>
entities_with_local_changes =
bookmark_tracker_->GetEntitiesWithLocalChanges();
syncer::CommitRequestDataList commit_requests;
for (const SyncedBookmarkTrackerEntity* entity :
entities_with_local_changes) {
if (commit_requests.size() >= max_entries) {
break;
}
DCHECK(entity);
DCHECK(entity->IsUnsynced());
const sync_pb::EntityMetadata* metadata = entity->metadata();
auto data = std::make_unique<syncer::EntityData>();
data->id = metadata->server_id();
data->creation_time = syncer::ProtoTimeToTime(metadata->creation_time());
data->modification_time =
syncer::ProtoTimeToTime(metadata->modification_time());
DCHECK(!metadata->client_tag_hash().empty());
data->client_tag_hash =
syncer::ClientTagHash::FromHashed(metadata->client_tag_hash());
DCHECK(metadata->is_deleted() ||
data->client_tag_hash ==
syncer::ClientTagHash::FromUnhashed(
syncer::BOOKMARKS,
entity->bookmark_node()->guid().AsLowercaseString()));
if (!metadata->is_deleted()) {
const bookmarks::BookmarkNode* node = entity->bookmark_node();
DCHECK(!node->is_permanent_node());
// Skip current entity if its favicon is not loaded yet. It will be
// committed once the favicon is loaded in
// BookmarkModelObserverImpl::BookmarkNodeFaviconChanged.
if (!node->is_folder() && !node->is_favicon_loaded()) {
// Force the favicon to be loaded. The worker will be nudged for commit
// in BookmarkModelObserverImpl::BookmarkNodeFaviconChanged() once
// favicon is loaded.
bookmark_model_->GetFavicon(node);
continue;
}
DCHECK(node);
DCHECK_EQ(syncer::ClientTagHash::FromUnhashed(
syncer::BOOKMARKS, node->guid().AsLowercaseString()),
syncer::ClientTagHash::FromHashed(metadata->client_tag_hash()));
const bookmarks::BookmarkNode* parent = node->parent();
const SyncedBookmarkTrackerEntity* parent_entity =
bookmark_tracker_->GetEntityForBookmarkNode(parent);
DCHECK(parent_entity);
data->legacy_parent_id = parent_entity->metadata()->server_id();
// Assign specifics only for the non-deletion case. In case of deletion,
// EntityData should contain empty specifics to indicate deletion.
data->specifics = CreateSpecificsFromBookmarkNode(
node, bookmark_model_, metadata->unique_position(),
/*force_favicon_load=*/true);
// TODO(crbug.com/1058376): check after finishing if we need to use full
// title instead of legacy canonicalized one.
data->name = data->specifics.bookmark().legacy_canonicalized_title();
}
auto request = std::make_unique<syncer::CommitRequestData>();
request->entity = std::move(data);
request->sequence_number = metadata->sequence_number();
request->base_version = metadata->server_version();
// Specifics hash has been computed in the tracker when this entity has been
// added/updated.
request->specifics_hash = metadata->specifics_hash();
bookmark_tracker_->MarkCommitMayHaveStarted(entity);
commit_requests.push_back(std::move(request));
}
return commit_requests;
}
} // namespace sync_bookmarks