blob: b016e9ea63ae5f4c6e7d284f8163311dc7b0703c [file] [log] [blame]
// Copyright (c) 2012 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 "chrome/browser/extensions/api/storage/settings_namespace.h"
#include "chrome/browser/extensions/api/storage/settings_sync_processor.h"
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "content/public/browser/browser_thread.h"
#include "sync/api/sync_change_processor.h"
#include "sync/api/sync_data.h"
#include "sync/protocol/extension_setting_specifics.pb.h"
using content::BrowserThread;
namespace extensions {
SettingsSyncProcessor::SettingsSyncProcessor(
const std::string& extension_id,
syncer::ModelType type,
syncer::SyncChangeProcessor* sync_processor)
: extension_id_(extension_id),
type_(type),
sync_processor_(sync_processor),
initialized_(false) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
CHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
CHECK(sync_processor);
}
SettingsSyncProcessor::~SettingsSyncProcessor() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
}
void SettingsSyncProcessor::Init(const base::DictionaryValue& initial_state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
CHECK(!initialized_) << "Init called multiple times";
for (base::DictionaryValue::Iterator i(initial_state); !i.IsAtEnd();
i.Advance())
synced_keys_.insert(i.key());
initialized_ = true;
}
syncer::SyncError SettingsSyncProcessor::SendChanges(
const ValueStoreChangeList& changes) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
CHECK(initialized_) << "Init not called";
syncer::SyncChangeList sync_changes;
std::set<std::string> added_keys;
std::set<std::string> deleted_keys;
for (ValueStoreChangeList::const_iterator i = changes.begin();
i != changes.end(); ++i) {
const std::string& key = i->key();
const Value* value = i->new_value();
if (value) {
if (synced_keys_.count(key)) {
// New value, key is synced; send ACTION_UPDATE.
sync_changes.push_back(settings_sync_util::CreateUpdate(
extension_id_, key, *value, type_));
} else {
// New value, key is not synced; send ACTION_ADD.
sync_changes.push_back(settings_sync_util::CreateAdd(
extension_id_, key, *value, type_));
added_keys.insert(key);
}
} else {
if (synced_keys_.count(key)) {
// Clearing value, key is synced; send ACTION_DELETE.
sync_changes.push_back(settings_sync_util::CreateDelete(
extension_id_, key, type_));
deleted_keys.insert(key);
} else {
LOG(WARNING) << "Deleted " << key << " but not in synced_keys_";
}
}
}
if (sync_changes.empty())
return syncer::SyncError();
syncer::SyncError error =
sync_processor_->ProcessSyncChanges(FROM_HERE, sync_changes);
if (error.IsSet())
return error;
synced_keys_.insert(added_keys.begin(), added_keys.end());
for (std::set<std::string>::iterator i = deleted_keys.begin();
i != deleted_keys.end(); ++i) {
synced_keys_.erase(*i);
}
return syncer::SyncError();
}
void SettingsSyncProcessor::NotifyChanges(const ValueStoreChangeList& changes) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
CHECK(initialized_) << "Init not called";
for (ValueStoreChangeList::const_iterator i = changes.begin();
i != changes.end(); ++i) {
if (i->new_value())
synced_keys_.insert(i->key());
else
synced_keys_.erase(i->key());
}
}
} // namespace extensions