1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/storage/settings_sync_processor.h"
#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "components/sync/model/model_error.h"
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/protocol/extension_setting_specifics.pb.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/settings_namespace.h"
#include "extensions/common/extension_id.h"
namespace extensions {
SettingsSyncProcessor::SettingsSyncProcessor(
const ExtensionId& extension_id,
syncer::DataType type,
syncer::SyncChangeProcessor* sync_processor)
: extension_id_(extension_id),
type_(type),
sync_processor_(sync_processor),
initialized_(false) {
DCHECK(IsOnBackendSequence());
CHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
CHECK(sync_processor);
}
SettingsSyncProcessor::~SettingsSyncProcessor() {
DCHECK(IsOnBackendSequence());
}
void SettingsSyncProcessor::Init(const base::Value::Dict& initial_state) {
DCHECK(IsOnBackendSequence());
CHECK(!initialized_) << "Init called multiple times";
for (auto iter : initial_state) {
synced_keys_.insert(iter.first);
}
initialized_ = true;
}
std::optional<syncer::ModelError> SettingsSyncProcessor::SendChanges(
const value_store::ValueStoreChangeList& changes) {
DCHECK(IsOnBackendSequence());
CHECK(initialized_) << "Init not called";
syncer::SyncChangeList sync_changes;
std::set<std::string> added_keys;
std::set<std::string> deleted_keys;
for (const auto& i : changes) {
if (i.new_value) {
if (synced_keys_.count(i.key)) {
// New value, key is synced; send ACTION_UPDATE.
sync_changes.push_back(settings_sync_util::CreateUpdate(
extension_id_, i.key, *i.new_value, type_));
} else {
// New value, key is not synced; send ACTION_ADD.
sync_changes.push_back(settings_sync_util::CreateAdd(
extension_id_, i.key, *i.new_value, type_));
added_keys.insert(i.key);
}
} else {
if (synced_keys_.count(i.key)) {
// Clearing value, key is synced; send ACTION_DELETE.
sync_changes.push_back(
settings_sync_util::CreateDelete(extension_id_, i.key, type_));
deleted_keys.insert(i.key);
} else {
LOG(WARNING) << "Deleted " << i.key << " but not in synced_keys_";
}
}
}
if (sync_changes.empty())
return std::nullopt;
std::optional<syncer::ModelError> error =
sync_processor_->ProcessSyncChanges(FROM_HERE, sync_changes);
if (error.has_value())
return error;
synced_keys_.insert(added_keys.begin(), added_keys.end());
for (const auto& deleted_key : deleted_keys) {
synced_keys_.erase(deleted_key);
}
return std::nullopt;
}
void SettingsSyncProcessor::NotifyChanges(
const value_store::ValueStoreChangeList& changes) {
DCHECK(IsOnBackendSequence());
CHECK(initialized_) << "Init not called";
for (const auto& i : changes) {
if (i.new_value)
synced_keys_.insert(i.key);
else
synced_keys_.erase(i.key);
}
}
} // namespace extensions
|