Commit 6387496e authored by kalman's avatar kalman Committed by Commit bot

Remove a bunch of DeepCopy() calls in the chrome.storage API.

DeepCopy() is expensive and we're doing a lot of it, transferring ownership is
better. I also tidied up some code here and there, like C++11 niceties,
removing unnecessary linked_ptrs, and better commenting.

R=rdevlin.cronin@chromium.org

Review URL: https://codereview.chromium.org/1141963002

Cr-Commit-Position: refs/heads/master@{#330597}
parent 8707fef0
...@@ -13,80 +13,17 @@ ...@@ -13,80 +13,17 @@
namespace extensions { namespace extensions {
SettingSyncData::SettingSyncData( SettingSyncData::SettingSyncData(const syncer::SyncChange& sync_change)
const syncer::SyncChange& sync_change) { : change_type_(sync_change.change_type()) {
Init(sync_change.change_type(), sync_change.sync_data()); ExtractSyncData(sync_change.sync_data());
} }
SettingSyncData::SettingSyncData( SettingSyncData::SettingSyncData(const syncer::SyncData& sync_data)
const syncer::SyncData& sync_data) { : change_type_(syncer::SyncChange::ACTION_INVALID) {
Init(syncer::SyncChange::ACTION_INVALID, sync_data); ExtractSyncData(sync_data);
} }
void SettingSyncData::Init( SettingSyncData::SettingSyncData(syncer::SyncChange::SyncChangeType change_type,
syncer::SyncChange::SyncChangeType change_type,
const syncer::SyncData& sync_data) {
DCHECK(!internal_.get());
sync_pb::EntitySpecifics specifics = sync_data.GetSpecifics();
// The data must only be either extension or app specfics.
DCHECK_NE(specifics.has_extension_setting(),
specifics.has_app_setting());
if (specifics.has_extension_setting()) {
InitFromExtensionSettingSpecifics(
change_type,
specifics.extension_setting());
} else if (specifics.has_app_setting()) {
InitFromExtensionSettingSpecifics(
change_type,
specifics.app_setting().extension_setting());
}
}
void SettingSyncData::InitFromExtensionSettingSpecifics(
syncer::SyncChange::SyncChangeType change_type,
const sync_pb::ExtensionSettingSpecifics& specifics) {
DCHECK(!internal_.get());
scoped_ptr<base::Value> value(
base::JSONReader::Read(specifics.value()));
if (!value.get()) {
LOG(WARNING) << "Specifics for " << specifics.extension_id() << "/" <<
specifics.key() << " had bad JSON for value: " << specifics.value();
value.reset(new base::DictionaryValue());
}
internal_ = new Internal(
change_type,
specifics.extension_id(),
specifics.key(),
value.Pass());
}
SettingSyncData::SettingSyncData(
syncer::SyncChange::SyncChangeType change_type,
const std::string& extension_id,
const std::string& key,
scoped_ptr<base::Value> value)
: internal_(new Internal(change_type, extension_id, key, value.Pass())) {}
SettingSyncData::~SettingSyncData() {}
syncer::SyncChange::SyncChangeType SettingSyncData::change_type() const {
return internal_->change_type_;
}
const std::string& SettingSyncData::extension_id() const {
return internal_->extension_id_;
}
const std::string& SettingSyncData::key() const {
return internal_->key_;
}
const base::Value& SettingSyncData::value() const {
return *internal_->value_;
}
SettingSyncData::Internal::Internal(
syncer::SyncChange::SyncChangeType change_type,
const std::string& extension_id, const std::string& extension_id,
const std::string& key, const std::string& key,
scoped_ptr<base::Value> value) scoped_ptr<base::Value> value)
...@@ -94,9 +31,33 @@ SettingSyncData::Internal::Internal( ...@@ -94,9 +31,33 @@ SettingSyncData::Internal::Internal(
extension_id_(extension_id), extension_id_(extension_id),
key_(key), key_(key),
value_(value.Pass()) { value_(value.Pass()) {
DCHECK(value_.get());
} }
SettingSyncData::Internal::~Internal() {} SettingSyncData::~SettingSyncData() {}
scoped_ptr<base::Value> SettingSyncData::PassValue() {
DCHECK(value_) << "value has already been Pass()ed";
return value_.Pass();
}
void SettingSyncData::ExtractSyncData(const syncer::SyncData& sync_data) {
sync_pb::EntitySpecifics specifics = sync_data.GetSpecifics();
// The specifics are exclusively either extension or app settings.
DCHECK_NE(specifics.has_extension_setting(), specifics.has_app_setting());
const sync_pb::ExtensionSettingSpecifics& extension_specifics =
specifics.has_extension_setting()
? specifics.extension_setting()
: specifics.app_setting().extension_setting();
extension_id_ = extension_specifics.extension_id();
key_ = extension_specifics.key();
value_.reset(base::JSONReader::Read(extension_specifics.value()));
if (!value_) {
LOG(WARNING) << "Specifics for " << extension_id_ << "/" << key_
<< " had bad JSON for value: " << extension_specifics.value();
value_.reset(new base::DictionaryValue());
}
}
} // namespace extensions } // namespace extensions
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
#ifndef CHROME_BROWSER_EXTENSIONS_API_STORAGE_SETTING_SYNC_DATA_H_ #ifndef CHROME_BROWSER_EXTENSIONS_API_STORAGE_SETTING_SYNC_DATA_H_
#define CHROME_BROWSER_EXTENSIONS_API_STORAGE_SETTING_SYNC_DATA_H_ #define CHROME_BROWSER_EXTENSIONS_API_STORAGE_SETTING_SYNC_DATA_H_
#include "base/memory/ref_counted.h" #include <string>
#include "base/macros.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/values.h" #include "base/values.h"
#include "sync/api/sync_change.h" #include "sync/api/sync_change.h"
...@@ -39,52 +42,34 @@ class SettingSyncData { ...@@ -39,52 +42,34 @@ class SettingSyncData {
~SettingSyncData(); ~SettingSyncData();
// Returns the type of the sync change; may be ACTION_INVALID. // May return ACTION_INVALID if this object represents sync data that isn't
syncer::SyncChange::SyncChangeType change_type() const; // associated with a sync operation.
syncer::SyncChange::SyncChangeType change_type() const {
// Returns the extension id the setting is for. return change_type_;
const std::string& extension_id() const; }
const std::string& extension_id() const { return extension_id_; }
const std::string& key() const { return key_; }
// value() cannot be called if PassValue() has been called.
const base::Value& value() const { return *value_; }
// Returns the settings key. // Releases ownership of the value to the caller. Neither value() nor
const std::string& key() const; // PassValue() can be after this.
scoped_ptr<base::Value> PassValue();
// Returns the value of the setting.
const base::Value& value() const;
private: private:
// Ref-counted container for the data. // Populates the extension ID, key, and value from |sync_data|. This will be
// TODO(kalman): Use browser_sync::Immutable<Internal>. // either an extension or app settings data type.
class Internal : public base::RefCountedThreadSafe<Internal> { void ExtractSyncData(const syncer::SyncData& sync_data);
public:
Internal(
syncer::SyncChange::SyncChangeType change_type,
const std::string& extension_id,
const std::string& key,
scoped_ptr<base::Value> value);
syncer::SyncChange::SyncChangeType change_type_; syncer::SyncChange::SyncChangeType change_type_;
std::string extension_id_; std::string extension_id_;
std::string key_; std::string key_;
scoped_ptr<base::Value> value_; scoped_ptr<base::Value> value_;
private: DISALLOW_COPY_AND_ASSIGN(SettingSyncData);
friend class base::RefCountedThreadSafe<Internal>;
~Internal();
};
// Initializes internal_ from sync data for an extension or app setting.
void Init(syncer::SyncChange::SyncChangeType change_type,
const syncer::SyncData& sync_data);
// Initializes internal_ from extension specifics.
void InitFromExtensionSettingSpecifics(
syncer::SyncChange::SyncChangeType change_type,
const sync_pb::ExtensionSettingSpecifics& specifics);
scoped_refptr<Internal> internal_;
}; };
typedef std::vector<SettingSyncData> SettingSyncDataList; typedef ScopedVector<SettingSyncData> SettingSyncDataList;
} // namespace extensions } // namespace extensions
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
...@@ -42,6 +43,11 @@ namespace { ...@@ -42,6 +43,11 @@ namespace {
// To save typing ValueStore::DEFAULTS everywhere. // To save typing ValueStore::DEFAULTS everywhere.
const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS; const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
// More saving typing. Maps extension IDs to a list of sync changes for that
// extension.
using SettingSyncDataMultimap =
std::map<std::string, linked_ptr<SettingSyncDataList>>;
// Gets the pretty-printed JSON for a value. // Gets the pretty-printed JSON for a value.
static std::string GetJson(const base::Value& value) { static std::string GetJson(const base::Value& value) {
std::string json; std::string json;
...@@ -106,7 +112,7 @@ class MockSyncChangeProcessor : public syncer::SyncChangeProcessor { ...@@ -106,7 +112,7 @@ class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
} }
for (syncer::SyncChangeList::const_iterator it = change_list.begin(); for (syncer::SyncChangeList::const_iterator it = change_list.begin();
it != change_list.end(); ++it) { it != change_list.end(); ++it) {
changes_.push_back(SettingSyncData(*it)); changes_.push_back(new SettingSyncData(*it));
} }
return syncer::SyncError(); return syncer::SyncError();
} }
...@@ -129,23 +135,19 @@ class MockSyncChangeProcessor : public syncer::SyncChangeProcessor { ...@@ -129,23 +135,19 @@ class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
// Returns the only change for a given extension setting. If there is not // Returns the only change for a given extension setting. If there is not
// exactly 1 change for that key, a test assertion will fail. // exactly 1 change for that key, a test assertion will fail.
SettingSyncData GetOnlyChange( SettingSyncData* GetOnlyChange(const std::string& extension_id,
const std::string& extension_id, const std::string& key) { const std::string& key) {
SettingSyncDataList matching_changes; std::vector<SettingSyncData*> matching_changes;
for (SettingSyncDataList::iterator it = changes_.begin(); for (SettingSyncDataList::iterator it = changes_.begin();
it != changes_.end(); ++it) { it != changes_.end(); ++it) {
if (it->extension_id() == extension_id && it->key() == key) { if ((*it)->extension_id() == extension_id && (*it)->key() == key) {
matching_changes.push_back(*it); matching_changes.push_back(*it);
} }
} }
if (matching_changes.empty()) { if (matching_changes.empty()) {
ADD_FAILURE() << "No matching changes for " << extension_id << "/" << ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
key << " (out of " << changes_.size() << ")"; key << " (out of " << changes_.size() << ")";
return SettingSyncData(syncer::SyncChange::ACTION_INVALID, return nullptr;
std::string(),
std::string(),
scoped_ptr<base::Value>(
new base::DictionaryValue()));
} }
if (matching_changes.size() != 1u) { if (matching_changes.size() != 1u) {
ADD_FAILURE() << matching_changes.size() << " matching changes for " << ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
...@@ -243,15 +245,18 @@ class ExtensionSettingsSyncTest : public testing::Test { ...@@ -243,15 +245,18 @@ class ExtensionSettingsSyncTest : public testing::Test {
// Gets all the sync data from the SyncableService for a sync type as a map // Gets all the sync data from the SyncableService for a sync type as a map
// from extension id to its sync data. // from extension id to its sync data.
std::map<std::string, SettingSyncDataList> GetAllSyncData( SettingSyncDataMultimap GetAllSyncData(syncer::ModelType model_type) {
syncer::ModelType model_type) {
syncer::SyncDataList as_list = syncer::SyncDataList as_list =
GetSyncableService(model_type)->GetAllSyncData(model_type); GetSyncableService(model_type)->GetAllSyncData(model_type);
std::map<std::string, SettingSyncDataList> as_map; SettingSyncDataMultimap as_map;
for (syncer::SyncDataList::iterator it = as_list.begin(); for (syncer::SyncDataList::iterator it = as_list.begin();
it != as_list.end(); ++it) { it != as_list.end(); ++it) {
SettingSyncData sync_data(*it); SettingSyncData* sync_data = new SettingSyncData(*it);
as_map[sync_data.extension_id()].push_back(sync_data); linked_ptr<SettingSyncDataList>& list_for_extension =
as_map[sync_data->extension_id()];
if (!list_for_extension.get())
list_for_extension.reset(new SettingSyncDataList());
list_for_extension->push_back(sync_data);
} }
return as_map; return as_map;
} }
...@@ -312,13 +317,12 @@ TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) { ...@@ -312,13 +317,12 @@ TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
storage1->Set(DEFAULTS, "foo", value1); storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "bar", value2); storage2->Set(DEFAULTS, "bar", value2);
std::map<std::string, SettingSyncDataList> all_sync_data = SettingSyncDataMultimap all_sync_data = GetAllSyncData(model_type);
GetAllSyncData(model_type);
EXPECT_EQ(2u, all_sync_data.size()); EXPECT_EQ(2u, all_sync_data.size());
EXPECT_EQ(1u, all_sync_data["s1"].size()); EXPECT_EQ(1u, all_sync_data["s1"]->size());
EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value()); EXPECT_PRED_FORMAT2(ValuesEq, &value1, &(*all_sync_data["s1"])[0]->value());
EXPECT_EQ(1u, all_sync_data["s2"].size()); EXPECT_EQ(1u, all_sync_data["s2"]->size());
EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value()); EXPECT_PRED_FORMAT2(ValuesEq, &value2, &(*all_sync_data["s2"])[0]->value());
syncer::SyncDataList sync_data; syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData( sync_data.push_back(settings_sync_util::CreateData(
...@@ -343,9 +347,9 @@ TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) { ...@@ -343,9 +347,9 @@ TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
storage1->Set(DEFAULTS, "foo", value2); storage1->Set(DEFAULTS, "foo", value2);
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo"); SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
EXPECT_TRUE(value2.Equals(&change.value())); EXPECT_TRUE(value2.Equals(&change->value()));
GetSyncableService(model_type)->StopSyncing(model_type); GetSyncableService(model_type)->StopSyncing(model_type);
} }
...@@ -373,12 +377,12 @@ TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) { ...@@ -373,12 +377,12 @@ TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
// All settings should have been pushed to sync. // All settings should have been pushed to sync.
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo"); SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
EXPECT_TRUE(value1.Equals(&change.value())); EXPECT_TRUE(value1.Equals(&change->value()));
change = sync_processor_->GetOnlyChange("s2", "bar"); change = sync_processor_->GetOnlyChange("s2", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
EXPECT_TRUE(value2.Equals(&change.value())); EXPECT_TRUE(value2.Equals(&change->value()));
GetSyncableService(model_type)->StopSyncing(model_type); GetSyncableService(model_type)->StopSyncing(model_type);
} }
...@@ -537,18 +541,18 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) { ...@@ -537,18 +541,18 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) {
storage3->Set(DEFAULTS, "foo", value1); storage3->Set(DEFAULTS, "foo", value1);
storage4->Set(DEFAULTS, "foo", value1); storage4->Set(DEFAULTS, "foo", value1);
SettingSyncData change = sync_processor_->GetOnlyChange("s1", "bar"); SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
EXPECT_TRUE(value2.Equals(&change.value())); EXPECT_TRUE(value2.Equals(&change->value()));
sync_processor_->GetOnlyChange("s2", "bar"); sync_processor_->GetOnlyChange("s2", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
EXPECT_TRUE(value2.Equals(&change.value())); EXPECT_TRUE(value2.Equals(&change->value()));
change = sync_processor_->GetOnlyChange("s3", "foo"); change = sync_processor_->GetOnlyChange("s3", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
EXPECT_TRUE(value1.Equals(&change.value())); EXPECT_TRUE(value1.Equals(&change->value()));
change = sync_processor_->GetOnlyChange("s4", "foo"); change = sync_processor_->GetOnlyChange("s4", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
EXPECT_TRUE(value1.Equals(&change.value())); EXPECT_TRUE(value1.Equals(&change->value()));
// Change something locally, storage1/3 the new setting and storage2/4 the // Change something locally, storage1/3 the new setting and storage2/4 the
// initial setting, for all combinations of local vs sync intialisation and // initial setting, for all combinations of local vs sync intialisation and
...@@ -560,17 +564,17 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) { ...@@ -560,17 +564,17 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) {
storage4->Set(DEFAULTS, "foo", value2); storage4->Set(DEFAULTS, "foo", value2);
change = sync_processor_->GetOnlyChange("s1", "bar"); change = sync_processor_->GetOnlyChange("s1", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
EXPECT_TRUE(value1.Equals(&change.value())); EXPECT_TRUE(value1.Equals(&change->value()));
change = sync_processor_->GetOnlyChange("s2", "foo"); change = sync_processor_->GetOnlyChange("s2", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
EXPECT_TRUE(value2.Equals(&change.value())); EXPECT_TRUE(value2.Equals(&change->value()));
change = sync_processor_->GetOnlyChange("s3", "bar"); change = sync_processor_->GetOnlyChange("s3", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
EXPECT_TRUE(value1.Equals(&change.value())); EXPECT_TRUE(value1.Equals(&change->value()));
change = sync_processor_->GetOnlyChange("s4", "foo"); change = sync_processor_->GetOnlyChange("s4", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
EXPECT_TRUE(value2.Equals(&change.value())); EXPECT_TRUE(value2.Equals(&change->value()));
// Remove something locally, storage1/3 the new setting and storage2/4 the // Remove something locally, storage1/3 the new setting and storage2/4 the
// initial setting, for all combinations of local vs sync intialisation and // initial setting, for all combinations of local vs sync intialisation and
...@@ -581,18 +585,14 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) { ...@@ -581,18 +585,14 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) {
storage3->Remove("foo"); storage3->Remove("foo");
storage4->Remove("bar"); storage4->Remove("bar");
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
syncer::SyncChange::ACTION_DELETE, sync_processor_->GetOnlyChange("s1", "foo")->change_type());
sync_processor_->GetOnlyChange("s1", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
EXPECT_EQ( sync_processor_->GetOnlyChange("s2", "bar")->change_type());
syncer::SyncChange::ACTION_DELETE, EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s2", "bar").change_type()); sync_processor_->GetOnlyChange("s3", "foo")->change_type());
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
syncer::SyncChange::ACTION_DELETE, sync_processor_->GetOnlyChange("s4", "bar")->change_type());
sync_processor_->GetOnlyChange("s3", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s4", "bar").change_type());
// Remove some nonexistent settings. // Remove some nonexistent settings.
sync_processor_->ClearChanges(); sync_processor_->ClearChanges();
...@@ -616,30 +616,22 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) { ...@@ -616,30 +616,22 @@ TEST_F(ExtensionSettingsSyncTest, PushToSync) {
storage3->Clear(); storage3->Clear();
storage4->Clear(); storage4->Clear();
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
syncer::SyncChange::ACTION_DELETE, sync_processor_->GetOnlyChange("s1", "foo")->change_type());
sync_processor_->GetOnlyChange("s1", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
EXPECT_EQ( sync_processor_->GetOnlyChange("s1", "bar")->change_type());
syncer::SyncChange::ACTION_DELETE, EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s1", "bar").change_type()); sync_processor_->GetOnlyChange("s2", "foo")->change_type());
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
syncer::SyncChange::ACTION_DELETE, sync_processor_->GetOnlyChange("s2", "bar")->change_type());
sync_processor_->GetOnlyChange("s2", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
EXPECT_EQ( sync_processor_->GetOnlyChange("s3", "foo")->change_type());
syncer::SyncChange::ACTION_DELETE, EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s2", "bar").change_type()); sync_processor_->GetOnlyChange("s3", "bar")->change_type());
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
syncer::SyncChange::ACTION_DELETE, sync_processor_->GetOnlyChange("s4", "foo")->change_type());
sync_processor_->GetOnlyChange("s3", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
EXPECT_EQ( sync_processor_->GetOnlyChange("s4", "bar")->change_type());
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s3", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s4", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s4", "bar").change_type());
GetSyncableService(model_type)->StopSyncing(model_type); GetSyncableService(model_type)->StopSyncing(model_type);
} }
...@@ -658,17 +650,17 @@ TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) { ...@@ -658,17 +650,17 @@ TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
storage1->Set(DEFAULTS, "foo", value1); storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "bar", value2); storage2->Set(DEFAULTS, "bar", value2);
std::map<std::string, SettingSyncDataList> extension_sync_data = SettingSyncDataMultimap extension_sync_data =
GetAllSyncData(syncer::EXTENSION_SETTINGS); GetAllSyncData(syncer::EXTENSION_SETTINGS);
EXPECT_EQ(1u, extension_sync_data.size()); EXPECT_EQ(1u, extension_sync_data.size());
EXPECT_EQ(1u, extension_sync_data["s1"].size()); EXPECT_EQ(1u, extension_sync_data["s1"]->size());
EXPECT_PRED_FORMAT2(ValuesEq, &value1, &extension_sync_data["s1"][0].value()); EXPECT_PRED_FORMAT2(ValuesEq, &value1,
&(*extension_sync_data["s1"])[0]->value());
std::map<std::string, SettingSyncDataList> app_sync_data = SettingSyncDataMultimap app_sync_data = GetAllSyncData(syncer::APP_SETTINGS);
GetAllSyncData(syncer::APP_SETTINGS);
EXPECT_EQ(1u, app_sync_data.size()); EXPECT_EQ(1u, app_sync_data.size());
EXPECT_EQ(1u, app_sync_data["s2"].size()); EXPECT_EQ(1u, app_sync_data["s2"]->size());
EXPECT_PRED_FORMAT2(ValuesEq, &value2, &app_sync_data["s2"][0].value()); EXPECT_PRED_FORMAT2(ValuesEq, &value2, &(*app_sync_data["s2"])[0]->value());
// Stop each separately, there should be no changes either time. // Stop each separately, there should be no changes either time.
syncer::SyncDataList sync_data; syncer::SyncDataList sync_data;
...@@ -750,9 +742,8 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) { ...@@ -750,9 +742,8 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
good->Set(DEFAULTS, "bar", barValue); good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue); bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "bar")->change_type());
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
{ {
...@@ -798,9 +789,8 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) { ...@@ -798,9 +789,8 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
good->Set(DEFAULTS, "bar", fooValue); good->Set(DEFAULTS, "bar", fooValue);
bad->Set(DEFAULTS, "bar", fooValue); bad->Set(DEFAULTS, "bar", fooValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "bar")->change_type());
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
{ {
...@@ -854,15 +844,12 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) { ...@@ -854,15 +844,12 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
// Local settings will have been pushed to sync, since it's empty (in this // Local settings will have been pushed to sync, since it's empty (in this
// test; presumably it wouldn't be live, since we've been getting changes). // test; presumably it wouldn't be live, since we've been getting changes).
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "bar")->change_type());
syncer::SyncChange::ACTION_ADD, EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type()); sync_processor_->GetOnlyChange("bad", "bar")->change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(3u, sync_processor_->changes().size()); EXPECT_EQ(3u, sync_processor_->changes().size());
// Live local changes now get pushed, too. // Live local changes now get pushed, too.
...@@ -870,12 +857,10 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) { ...@@ -870,12 +857,10 @@ TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
good->Set(DEFAULTS, "bar", barValue); good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue); bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "bar")->change_type());
sync_processor_->GetOnlyChange("good", "bar").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
EXPECT_EQ( sync_processor_->GetOnlyChange("bad", "bar")->change_type());
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
// And ProcessSyncChanges work, too. // And ProcessSyncChanges work, too.
...@@ -973,9 +958,8 @@ TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) { ...@@ -973,9 +958,8 @@ TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
good->Set(DEFAULTS, "foo", barValue); good->Set(DEFAULTS, "foo", barValue);
bad->Set(DEFAULTS, "foo", barValue); bad->Set(DEFAULTS, "foo", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
// No more changes received from sync should go to bad. // No more changes received from sync should go to bad.
...@@ -1036,24 +1020,20 @@ TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) { ...@@ -1036,24 +1020,20 @@ TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
sync_processor_wrapper_.Pass(), sync_processor_wrapper_.Pass(),
make_scoped_ptr(new syncer::SyncErrorFactoryMock())); make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
EXPECT_EQ( sync_processor_->GetOnlyChange("bad", "foo")->change_type());
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
sync_processor_->ClearChanges(); sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", barValue); good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue); bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "bar")->change_type());
sync_processor_->GetOnlyChange("good", "bar").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
EXPECT_EQ( sync_processor_->GetOnlyChange("bad", "bar")->change_type());
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
} }
...@@ -1084,9 +1064,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) { ...@@ -1084,9 +1064,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
make_scoped_ptr(new syncer::SyncErrorFactoryMock())); make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK); testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
// bad should now be disabled for sync. // bad should now be disabled for sync.
...@@ -1094,9 +1073,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) { ...@@ -1094,9 +1073,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
good->Set(DEFAULTS, "bar", barValue); good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue); bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "bar")->change_type());
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
{ {
...@@ -1136,30 +1114,24 @@ TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) { ...@@ -1136,30 +1114,24 @@ TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
sync_processor_wrapper_.Pass(), sync_processor_wrapper_.Pass(),
make_scoped_ptr(new syncer::SyncErrorFactoryMock())); make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "bar")->change_type());
syncer::SyncChange::ACTION_ADD, EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type()); sync_processor_->GetOnlyChange("bad", "foo")->change_type());
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("bad", "bar")->change_type());
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(4u, sync_processor_->changes().size()); EXPECT_EQ(4u, sync_processor_->changes().size());
sync_processor_->ClearChanges(); sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", fooValue); good->Set(DEFAULTS, "bar", fooValue);
bad->Set(DEFAULTS, "bar", fooValue); bad->Set(DEFAULTS, "bar", fooValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "bar")->change_type());
sync_processor_->GetOnlyChange("good", "bar").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "bar")->change_type());
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
} }
...@@ -1193,9 +1165,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) { ...@@ -1193,9 +1165,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
good->Set(DEFAULTS, "foo", barValue); good->Set(DEFAULTS, "foo", barValue);
bad->Set(DEFAULTS, "foo", barValue); bad->Set(DEFAULTS, "foo", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
// Changes from sync will be sent to good, not to bad. // Changes from sync will be sent to good, not to bad.
...@@ -1232,27 +1203,22 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) { ...@@ -1232,27 +1203,22 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
sync_processor_wrapper_.Pass(), sync_processor_wrapper_.Pass(),
make_scoped_ptr(new syncer::SyncErrorFactoryMock())); make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "bar")->change_type());
syncer::SyncChange::ACTION_ADD, EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type()); sync_processor_->GetOnlyChange("bad", "foo")->change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(3u, sync_processor_->changes().size()); EXPECT_EQ(3u, sync_processor_->changes().size());
sync_processor_->ClearChanges(); sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", fooValue); good->Set(DEFAULTS, "foo", fooValue);
bad->Set(DEFAULTS, "foo", fooValue); bad->Set(DEFAULTS, "foo", fooValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "foo")->change_type());
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
} }
...@@ -1282,9 +1248,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) { ...@@ -1282,9 +1248,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
bad->Set(DEFAULTS, "foo", fooValue); bad->Set(DEFAULTS, "foo", fooValue);
sync_processor_->set_fail_all_requests(false); sync_processor_->set_fail_all_requests(false);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
// No further changes should be sent from bad. // No further changes should be sent from bad.
...@@ -1292,9 +1257,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) { ...@@ -1292,9 +1257,8 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
good->Set(DEFAULTS, "foo", barValue); good->Set(DEFAULTS, "foo", barValue);
bad->Set(DEFAULTS, "foo", barValue); bad->Set(DEFAULTS, "foo", barValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size()); EXPECT_EQ(1u, sync_processor_->changes().size());
// Changes from sync will be sent to good, not to bad. // Changes from sync will be sent to good, not to bad.
...@@ -1331,27 +1295,22 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) { ...@@ -1331,27 +1295,22 @@ TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
sync_processor_wrapper_.Pass(), sync_processor_wrapper_.Pass(),
make_scoped_ptr(new syncer::SyncErrorFactoryMock())); make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
syncer::SyncChange::ACTION_ADD, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "bar")->change_type());
syncer::SyncChange::ACTION_ADD, EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type()); sync_processor_->GetOnlyChange("bad", "foo")->change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(3u, sync_processor_->changes().size()); EXPECT_EQ(3u, sync_processor_->changes().size());
sync_processor_->ClearChanges(); sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", fooValue); good->Set(DEFAULTS, "foo", fooValue);
bad->Set(DEFAULTS, "foo", fooValue); bad->Set(DEFAULTS, "foo", fooValue);
EXPECT_EQ( EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, sync_processor_->GetOnlyChange("good", "foo")->change_type());
sync_processor_->GetOnlyChange("good", "foo").change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
EXPECT_EQ( sync_processor_->GetOnlyChange("good", "foo")->change_type());
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size()); EXPECT_EQ(2u, sync_processor_->changes().size());
} }
...@@ -1437,11 +1396,11 @@ TEST_F(ExtensionSettingsSyncTest, Dots) { ...@@ -1437,11 +1396,11 @@ TEST_F(ExtensionSettingsSyncTest, Dots) {
storage->Set(DEFAULTS, "key.with.spot", *string_value); storage->Set(DEFAULTS, "key.with.spot", *string_value);
ASSERT_EQ(1u, sync_processor_->changes().size()); ASSERT_EQ(1u, sync_processor_->changes().size());
SettingSyncData sync_data = sync_processor_->changes()[0]; SettingSyncData* sync_data = sync_processor_->changes()[0];
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data.change_type()); EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data->change_type());
EXPECT_EQ("ext", sync_data.extension_id()); EXPECT_EQ("ext", sync_data->extension_id());
EXPECT_EQ("key.with.spot", sync_data.key()); EXPECT_EQ("key.with.spot", sync_data->key());
EXPECT_TRUE(sync_data.value().Equals(string_value.get())); EXPECT_TRUE(sync_data->value().Equals(string_value.get()));
} }
} }
......
...@@ -28,6 +28,10 @@ void AddAllSyncData(const std::string& extension_id, ...@@ -28,6 +28,10 @@ void AddAllSyncData(const std::string& extension_id,
} }
} }
scoped_ptr<base::DictionaryValue> EmptyDictionaryValue() {
return make_scoped_ptr(new base::DictionaryValue());
}
} // namespace } // namespace
SyncStorageBackend::SyncStorageBackend( SyncStorageBackend::SyncStorageBackend(
...@@ -52,13 +56,12 @@ SyncStorageBackend::~SyncStorageBackend() {} ...@@ -52,13 +56,12 @@ SyncStorageBackend::~SyncStorageBackend() {}
ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) { ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::DictionaryValue empty; return GetOrCreateStorageWithSyncData(extension_id, EmptyDictionaryValue());
return GetOrCreateStorageWithSyncData(extension_id, empty);
} }
SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData( SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData(
const std::string& extension_id, const std::string& extension_id,
const base::DictionaryValue& sync_data) const { scoped_ptr<base::DictionaryValue> sync_data) const {
DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK_CURRENTLY_ON(BrowserThread::FILE);
StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id);
...@@ -79,9 +82,9 @@ SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData( ...@@ -79,9 +82,9 @@ SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData(
if (sync_processor_.get()) { if (sync_processor_.get()) {
syncer::SyncError error = syncable_storage->StartSyncing( syncer::SyncError error = syncable_storage->StartSyncing(
sync_data, CreateSettingsSyncProcessor(extension_id).Pass()); sync_data.Pass(), CreateSettingsSyncProcessor(extension_id).Pass());
if (error.IsSet()) if (error.IsSet())
syncable_storage.get()->StopSyncing(); syncable_storage->StopSyncing();
} }
return syncable_storage.get(); return syncable_storage.get();
} }
...@@ -110,10 +113,8 @@ std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs() const { ...@@ -110,10 +113,8 @@ std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs() const {
// Storage areas can be in-memory as well as on disk. |storage_objs_| will // Storage areas can be in-memory as well as on disk. |storage_objs_| will
// contain all that are in-memory. // contain all that are in-memory.
for (StorageObjMap::iterator it = storage_objs_.begin(); for (const auto& storage_obj : storage_objs_) {
it != storage_objs_.end(); result.insert(storage_obj.first);
++it) {
result.insert(it->first);
} }
// Leveldb databases are directories inside |base_path_|. // Leveldb databases are directories inside |base_path_|.
...@@ -148,7 +149,7 @@ syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type) ...@@ -148,7 +149,7 @@ syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type)
it != known_extension_ids.end(); it != known_extension_ids.end();
++it) { ++it) {
ValueStore::ReadResult maybe_settings = ValueStore::ReadResult maybe_settings =
GetOrCreateStorageWithSyncData(*it, base::DictionaryValue())->Get(); GetOrCreateStorageWithSyncData(*it, EmptyDictionaryValue())->Get();
if (maybe_settings->HasError()) { if (maybe_settings->HasError()) {
LOG(WARNING) << "Failed to get settings for " << *it << ": " LOG(WARNING) << "Failed to get settings for " << *it << ": "
<< maybe_settings->error().message; << maybe_settings->error().message;
...@@ -175,54 +176,50 @@ syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing( ...@@ -175,54 +176,50 @@ syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing(
sync_error_factory_ = sync_error_factory.Pass(); sync_error_factory_ = sync_error_factory.Pass();
// Group the initial sync data by extension id. // Group the initial sync data by extension id.
std::map<std::string, linked_ptr<base::DictionaryValue> > grouped_sync_data; // The raw pointers are safe because ownership of each item is passed to
for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin(); // storage->StartSyncing or GetOrCreateStorageWithSyncData.
it != initial_sync_data.end(); std::map<std::string, base::DictionaryValue*> grouped_sync_data;
++it) {
SettingSyncData data(*it); for (const syncer::SyncData& sync_data : initial_sync_data) {
linked_ptr<base::DictionaryValue> sync_data = SettingSyncData data(sync_data);
grouped_sync_data[data.extension_id()]; // Yes this really is a reference to a pointer.
if (!sync_data.get()) { base::DictionaryValue*& settings = grouped_sync_data[data.extension_id()];
sync_data = if (!settings)
linked_ptr<base::DictionaryValue>(new base::DictionaryValue()); settings = new base::DictionaryValue();
grouped_sync_data[data.extension_id()] = sync_data; DCHECK(!settings->HasKey(data.key())) << "Duplicate settings for "
}
DCHECK(!sync_data->HasKey(data.key())) << "Duplicate settings for "
<< data.extension_id() << "/" << data.extension_id() << "/"
<< data.key(); << data.key();
sync_data->SetWithoutPathExpansion(data.key(), data.value().DeepCopy()); settings->SetWithoutPathExpansion(data.key(), data.PassValue());
} }
// Start syncing all existing storage areas. Any storage areas created in // Start syncing all existing storage areas. Any storage areas created in
// the future will start being synced as part of the creation process. // the future will start being synced as part of the creation process.
for (StorageObjMap::iterator it = storage_objs_.begin(); for (const auto& storage_obj : storage_objs_) {
it != storage_objs_.end(); const std::string& extension_id = storage_obj.first;
++it) { SyncableSettingsStorage* storage = storage_obj.second.get();
std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator
maybe_sync_data = grouped_sync_data.find(it->first); auto group = grouped_sync_data.find(extension_id);
syncer::SyncError error; syncer::SyncError error;
if (maybe_sync_data != grouped_sync_data.end()) { if (group != grouped_sync_data.end()) {
error = it->second->StartSyncing( error = storage->StartSyncing(
*maybe_sync_data->second, make_scoped_ptr(group->second),
CreateSettingsSyncProcessor(it->first).Pass()); CreateSettingsSyncProcessor(extension_id).Pass());
grouped_sync_data.erase(it->first); grouped_sync_data.erase(group);
} else { } else {
base::DictionaryValue empty; error = storage->StartSyncing(
error = it->second->StartSyncing( EmptyDictionaryValue(),
empty, CreateSettingsSyncProcessor(it->first).Pass()); CreateSettingsSyncProcessor(extension_id).Pass());
} }
if (error.IsSet()) if (error.IsSet())
it->second->StopSyncing(); storage->StopSyncing();
} }
// Eagerly create and init the rest of the storage areas that have sync data. // Eagerly create and init the rest of the storage areas that have sync data.
// Under normal circumstances (i.e. not first-time sync) this will be all of // Under normal circumstances (i.e. not first-time sync) this will be all of
// them. // them.
for (std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator it = for (const auto& group : grouped_sync_data) {
grouped_sync_data.begin(); GetOrCreateStorageWithSyncData(group.first, make_scoped_ptr(group.second));
it != grouped_sync_data.end();
++it) {
GetOrCreateStorageWithSyncData(it->first, *it->second);
} }
return syncer::SyncMergeResult(type); return syncer::SyncMergeResult(type);
...@@ -235,23 +232,24 @@ syncer::SyncError SyncStorageBackend::ProcessSyncChanges( ...@@ -235,23 +232,24 @@ syncer::SyncError SyncStorageBackend::ProcessSyncChanges(
DCHECK(sync_processor_.get()); DCHECK(sync_processor_.get());
// Group changes by extension, to pass all changes in a single method call. // Group changes by extension, to pass all changes in a single method call.
std::map<std::string, SettingSyncDataList> grouped_sync_data; // The raw pointers are safe because ownership of each item is passed to
for (syncer::SyncChangeList::const_iterator it = sync_changes.begin(); // storage->ProcessSyncChanges.
it != sync_changes.end(); std::map<std::string, SettingSyncDataList*> grouped_sync_data;
++it) {
SettingSyncData data(*it); for (const syncer::SyncChange& change : sync_changes) {
grouped_sync_data[data.extension_id()].push_back(data); scoped_ptr<SettingSyncData> data(new SettingSyncData(change));
SettingSyncDataList*& group = grouped_sync_data[data->extension_id()];
if (!group)
group = new SettingSyncDataList();
group->push_back(data.Pass());
} }
// Create any storage areas that don't exist yet but have sync data. // Create any storage areas that don't exist yet but have sync data.
base::DictionaryValue empty; for (const auto& group : grouped_sync_data) {
for (std::map<std::string, SettingSyncDataList>::iterator it =
grouped_sync_data.begin();
it != grouped_sync_data.end();
++it) {
SyncableSettingsStorage* storage = SyncableSettingsStorage* storage =
GetOrCreateStorageWithSyncData(it->first, empty); GetOrCreateStorageWithSyncData(group.first, EmptyDictionaryValue());
syncer::SyncError error = storage->ProcessSyncChanges(it->second); syncer::SyncError error =
storage->ProcessSyncChanges(make_scoped_ptr(group.second));
if (error.IsSet()) if (error.IsSet())
storage->StopSyncing(); storage->StopSyncing();
} }
...@@ -264,12 +262,10 @@ void SyncStorageBackend::StopSyncing(syncer::ModelType type) { ...@@ -264,12 +262,10 @@ void SyncStorageBackend::StopSyncing(syncer::ModelType type) {
DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS); DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
DCHECK_EQ(sync_type_, type); DCHECK_EQ(sync_type_, type);
for (StorageObjMap::iterator it = storage_objs_.begin(); for (const auto& storage_obj : storage_objs_) {
it != storage_objs_.end();
++it) {
// Some storage areas may have already stopped syncing if they had areas // Some storage areas may have already stopped syncing if they had areas
// and syncing was disabled, but StopSyncing is safe to call multiple times. // and syncing was disabled, but StopSyncing is safe to call multiple times.
it->second->StopSyncing(); storage_obj.second->StopSyncing();
} }
sync_processor_.reset(); sync_processor_.reset();
......
...@@ -67,7 +67,7 @@ class SyncStorageBackend : public syncer::SyncableService { ...@@ -67,7 +67,7 @@ class SyncStorageBackend : public syncer::SyncableService {
// initializing sync with some initial data if sync enabled. // initializing sync with some initial data if sync enabled.
SyncableSettingsStorage* GetOrCreateStorageWithSyncData( SyncableSettingsStorage* GetOrCreateStorageWithSyncData(
const std::string& extension_id, const std::string& extension_id,
const base::DictionaryValue& sync_data) const; scoped_ptr<base::DictionaryValue> sync_data) const;
// Gets all extension IDs known to extension settings. This may not be all // Gets all extension IDs known to extension settings. This may not be all
// installed extensions. // installed extensions.
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
#include "sync/api/sync_data.h" #include "sync/api/sync_data.h"
#include "sync/protocol/extension_setting_specifics.pb.h" #include "sync/protocol/extension_setting_specifics.pb.h"
namespace extensions {
using content::BrowserThread; using content::BrowserThread;
namespace extensions {
SyncableSettingsStorage::SyncableSettingsStorage( SyncableSettingsStorage::SyncableSettingsStorage(
const scoped_refptr<ObserverListThreadSafe<SettingsObserver> >& const scoped_refptr<ObserverListThreadSafe<SettingsObserver> >&
observers, observers,
...@@ -164,102 +164,97 @@ void SyncableSettingsStorage::SyncResultIfEnabled( ...@@ -164,102 +164,97 @@ void SyncableSettingsStorage::SyncResultIfEnabled(
// Sync-related methods. // Sync-related methods.
syncer::SyncError SyncableSettingsStorage::StartSyncing( syncer::SyncError SyncableSettingsStorage::StartSyncing(
const base::DictionaryValue& sync_state, scoped_ptr<base::DictionaryValue> sync_state,
scoped_ptr<SettingsSyncProcessor> sync_processor) { scoped_ptr<SettingsSyncProcessor> sync_processor) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(sync_state);
DCHECK(!sync_processor_.get()); DCHECK(!sync_processor_.get());
sync_processor_ = sync_processor.Pass(); sync_processor_ = sync_processor.Pass();
sync_processor_->Init(sync_state); sync_processor_->Init(*sync_state);
ReadResult maybe_settings = delegate_->Get(); ReadResult maybe_settings = delegate_->Get();
if (maybe_settings->HasError()) { if (maybe_settings->HasError()) {
return syncer::SyncError( return syncer::SyncError(
FROM_HERE, FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
syncer::SyncError::DATATYPE_ERROR,
base::StringPrintf("Failed to get settings: %s", base::StringPrintf("Failed to get settings: %s",
maybe_settings->error().message.c_str()), maybe_settings->error().message.c_str()),
sync_processor_->type()); sync_processor_->type());
} }
const base::DictionaryValue& settings = maybe_settings->settings(); scoped_ptr<base::DictionaryValue> current_settings =
return sync_state.empty() ? maybe_settings->PassSettings();
SendLocalSettingsToSync(settings) : return sync_state->empty() ? SendLocalSettingsToSync(current_settings.Pass())
OverwriteLocalSettingsWithSync(sync_state, settings); : OverwriteLocalSettingsWithSync(
sync_state.Pass(), current_settings.Pass());
} }
syncer::SyncError SyncableSettingsStorage::SendLocalSettingsToSync( syncer::SyncError SyncableSettingsStorage::SendLocalSettingsToSync(
const base::DictionaryValue& settings) { scoped_ptr<base::DictionaryValue> local_state) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK_CURRENTLY_ON(BrowserThread::FILE);
if (local_state->empty())
return syncer::SyncError();
// Transform the current settings into a list of sync changes.
ValueStoreChangeList changes; ValueStoreChangeList changes;
for (base::DictionaryValue::Iterator i(settings); !i.IsAtEnd(); i.Advance()) { while (!local_state->empty()) {
changes.push_back(ValueStoreChange(i.key(), NULL, i.value().DeepCopy())); // It's not possible to iterate over a DictionaryValue and modify it at the
// same time, so hack around that restriction.
std::string key = base::DictionaryValue::Iterator(*local_state).key();
scoped_ptr<base::Value> value;
local_state->RemoveWithoutPathExpansion(key, &value);
changes.push_back(ValueStoreChange(key, nullptr, value.release()));
} }
if (changes.empty())
return syncer::SyncError();
syncer::SyncError error = sync_processor_->SendChanges(changes); syncer::SyncError error = sync_processor_->SendChanges(changes);
if (error.IsSet()) if (error.IsSet())
StopSyncing(); StopSyncing();
return error; return error;
} }
syncer::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync( syncer::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync(
const base::DictionaryValue& sync_state, scoped_ptr<base::DictionaryValue> sync_state,
const base::DictionaryValue& settings) { scoped_ptr<base::DictionaryValue> local_state) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK_CURRENTLY_ON(BrowserThread::FILE);
// Treat this as a list of changes to sync and use ProcessSyncChanges. // This is implemented by building up a list of sync changes then sending
// This gives notifications etc for free. // those to ProcessSyncChanges. This generates events like onStorageChanged.
scoped_ptr<base::DictionaryValue> new_sync_state(sync_state.DeepCopy()); scoped_ptr<SettingSyncDataList> changes(new SettingSyncDataList());
SettingSyncDataList changes; for (base::DictionaryValue::Iterator it(*local_state); !it.IsAtEnd();
for (base::DictionaryValue::Iterator it(settings); it.Advance()) {
!it.IsAtEnd(); it.Advance()) {
scoped_ptr<base::Value> sync_value; scoped_ptr<base::Value> sync_value;
if (new_sync_state->RemoveWithoutPathExpansion(it.key(), &sync_value)) { if (sync_state->RemoveWithoutPathExpansion(it.key(), &sync_value)) {
if (sync_value->Equals(&it.value())) { if (sync_value->Equals(&it.value())) {
// Sync and local values are the same, no changes to send. // Sync and local values are the same, no changes to send.
} else { } else {
// Sync value is different, update local setting with new value. // Sync value is different, update local setting with new value.
changes.push_back( changes->push_back(
SettingSyncData( new SettingSyncData(syncer::SyncChange::ACTION_UPDATE,
syncer::SyncChange::ACTION_UPDATE, extension_id_, it.key(), sync_value.Pass()));
extension_id_,
it.key(),
sync_value.Pass()));
} }
} else { } else {
// Not synced, delete local setting. // Not synced, delete local setting.
changes.push_back( changes->push_back(new SettingSyncData(
SettingSyncData( syncer::SyncChange::ACTION_DELETE, extension_id_, it.key(),
syncer::SyncChange::ACTION_DELETE,
extension_id_,
it.key(),
scoped_ptr<base::Value>(new base::DictionaryValue()))); scoped_ptr<base::Value>(new base::DictionaryValue())));
} }
} }
// Add all new settings to local settings. // Add all new settings to local settings.
while (!new_sync_state->empty()) { while (!sync_state->empty()) {
base::DictionaryValue::Iterator first_entry(*new_sync_state); // It's not possible to iterate over a DictionaryValue and modify it at the
std::string key = first_entry.key(); // same time, so hack around that restriction.
std::string key = base::DictionaryValue::Iterator(*sync_state).key();
scoped_ptr<base::Value> value; scoped_ptr<base::Value> value;
CHECK(new_sync_state->RemoveWithoutPathExpansion(key, &value)); CHECK(sync_state->RemoveWithoutPathExpansion(key, &value));
changes.push_back( changes->push_back(new SettingSyncData(syncer::SyncChange::ACTION_ADD,
SettingSyncData( extension_id_, key, value.Pass()));
syncer::SyncChange::ACTION_ADD,
extension_id_,
key,
value.Pass()));
} }
if (changes.empty()) if (changes->empty())
return syncer::SyncError(); return syncer::SyncError();
return ProcessSyncChanges(changes.Pass());
return ProcessSyncChanges(changes);
} }
void SyncableSettingsStorage::StopSyncing() { void SyncableSettingsStorage::StopSyncing() {
...@@ -268,9 +263,9 @@ void SyncableSettingsStorage::StopSyncing() { ...@@ -268,9 +263,9 @@ void SyncableSettingsStorage::StopSyncing() {
} }
syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges(
const SettingSyncDataList& sync_changes) { scoped_ptr<SettingSyncDataList> sync_changes) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!sync_changes.empty()) << "No sync changes for " << extension_id_; DCHECK(!sync_changes->empty()) << "No sync changes for " << extension_id_;
if (!sync_processor_.get()) { if (!sync_processor_.get()) {
return syncer::SyncError( return syncer::SyncError(
...@@ -283,16 +278,15 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( ...@@ -283,16 +278,15 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges(
std::vector<syncer::SyncError> errors; std::vector<syncer::SyncError> errors;
ValueStoreChangeList changes; ValueStoreChangeList changes;
for (SettingSyncDataList::const_iterator it = sync_changes.begin(); for (SettingSyncDataList::iterator it = sync_changes->begin();
it != sync_changes.end(); ++it) { it != sync_changes->end(); ++it) {
DCHECK_EQ(extension_id_, it->extension_id()); DCHECK_EQ(extension_id_, (*it)->extension_id());
const std::string& key = (*it)->key();
const std::string& key = it->key(); scoped_ptr<base::Value> change_value = (*it)->PassValue();
const base::Value& value = it->value();
scoped_ptr<base::Value> current_value; scoped_ptr<base::Value> current_value;
{ {
ReadResult maybe_settings = Get(it->key()); ReadResult maybe_settings = Get(key);
if (maybe_settings->HasError()) { if (maybe_settings->HasError()) {
errors.push_back(syncer::SyncError( errors.push_back(syncer::SyncError(
FROM_HERE, FROM_HERE,
...@@ -309,29 +303,29 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( ...@@ -309,29 +303,29 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges(
syncer::SyncError error; syncer::SyncError error;
switch (it->change_type()) { switch ((*it)->change_type()) {
case syncer::SyncChange::ACTION_ADD: case syncer::SyncChange::ACTION_ADD:
if (!current_value.get()) { if (!current_value.get()) {
error = OnSyncAdd(key, value.DeepCopy(), &changes); error = OnSyncAdd(key, change_value.release(), &changes);
} else { } else {
// Already a value; hopefully a local change has beaten sync in a // Already a value; hopefully a local change has beaten sync in a
// race and it's not a bug, so pretend it's an update. // race and change's not a bug, so pretend change's an update.
LOG(WARNING) << "Got add from sync for existing setting " << LOG(WARNING) << "Got add from sync for existing setting " <<
extension_id_ << "/" << key; extension_id_ << "/" << key;
error = OnSyncUpdate( error = OnSyncUpdate(key, current_value.release(),
key, current_value.release(), value.DeepCopy(), &changes); change_value.release(), &changes);
} }
break; break;
case syncer::SyncChange::ACTION_UPDATE: case syncer::SyncChange::ACTION_UPDATE:
if (current_value.get()) { if (current_value.get()) {
error = OnSyncUpdate( error = OnSyncUpdate(key, current_value.release(),
key, current_value.release(), value.DeepCopy(), &changes); change_value.release(), &changes);
} else { } else {
// Similarly, pretend it's an add. // Similarly, pretend change's an add.
LOG(WARNING) << "Got update from sync for nonexistent setting" << LOG(WARNING) << "Got update from sync for nonexistent setting" <<
extension_id_ << "/" << key; extension_id_ << "/" << key;
error = OnSyncAdd(key, value.DeepCopy(), &changes); error = OnSyncAdd(key, change_value.release(), &changes);
} }
break; break;
...@@ -339,7 +333,7 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( ...@@ -339,7 +333,7 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges(
if (current_value.get()) { if (current_value.get()) {
error = OnSyncDelete(key, current_value.release(), &changes); error = OnSyncDelete(key, current_value.release(), &changes);
} else { } else {
// Similarly, ignore it. // Similarly, ignore change.
LOG(WARNING) << "Got delete from sync for nonexistent setting " << LOG(WARNING) << "Got delete from sync for nonexistent setting " <<
extension_id_ << "/" << key; extension_id_ << "/" << key;
} }
......
...@@ -55,29 +55,39 @@ class SyncableSettingsStorage : public ValueStore { ...@@ -55,29 +55,39 @@ class SyncableSettingsStorage : public ValueStore {
// ExtensionSettings), but with looser guarantees about when the methods // ExtensionSettings), but with looser guarantees about when the methods
// can be called. // can be called.
// Must only be called if sync isn't already active. // Starts syncing this storage area. Must only be called if sync isn't
// already active.
// |sync_state| is the current state of the extension settings in sync.
// |sync_processor| is used to write out any changes.
// Returns any error when trying to sync, or an empty error on success.
syncer::SyncError StartSyncing( syncer::SyncError StartSyncing(
const base::DictionaryValue& sync_state, scoped_ptr<base::DictionaryValue> sync_state,
scoped_ptr<SettingsSyncProcessor> sync_processor); scoped_ptr<SettingsSyncProcessor> sync_processor);
// May be called at any time (idempotent). // Stops syncing this storage area. May be called at any time (idempotent).
void StopSyncing(); void StopSyncing();
// May be called at any time; changes will be ignored if sync isn't active. // Pushes a list of sync changes into this storage area. May be called at any
syncer::SyncError ProcessSyncChanges(const SettingSyncDataList& sync_changes); // time, changes will be ignored if sync isn't active.
// Returns any error when trying to sync, or an empty error on success.
syncer::SyncError ProcessSyncChanges(
scoped_ptr<SettingSyncDataList> sync_changes);
private: private:
// Sends the changes from |result| to sync if it's enabled. // Sends the changes from |result| to sync if it's enabled.
void SyncResultIfEnabled(const ValueStore::WriteResult& result); void SyncResultIfEnabled(const ValueStore::WriteResult& result);
// Sends all local settings to sync (synced settings assumed to be empty). // Sends all local settings to sync. This assumes that there are no settings
// in sync yet.
// Returns any error when trying to sync, or an empty error on success.
syncer::SyncError SendLocalSettingsToSync( syncer::SyncError SendLocalSettingsToSync(
const base::DictionaryValue& settings); scoped_ptr<base::DictionaryValue> local_state);
// Overwrites local state with sync state. // Overwrites local state with sync state.
// Returns any error when trying to sync, or an empty error on success.
syncer::SyncError OverwriteLocalSettingsWithSync( syncer::SyncError OverwriteLocalSettingsWithSync(
const base::DictionaryValue& sync_state, scoped_ptr<base::DictionaryValue> sync_state,
const base::DictionaryValue& settings); scoped_ptr<base::DictionaryValue> local_state);
// Called when an Add/Update/Remove comes from sync. Ownership of Value*s // Called when an Add/Update/Remove comes from sync. Ownership of Value*s
// are taken. // are taken.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment