| Index: chrome/browser/extensions/api/storage/sync_storage_backend.cc
|
| diff --git a/chrome/browser/extensions/api/storage/settings_backend.cc b/chrome/browser/extensions/api/storage/sync_storage_backend.cc
|
| similarity index 71%
|
| copy from chrome/browser/extensions/api/storage/settings_backend.cc
|
| copy to chrome/browser/extensions/api/storage/sync_storage_backend.cc
|
| index df2bd134c0fa652bc7092e14042509ef32becf2f..22204bc2495a943c5688be89db0b7c43efbd942b 100644
|
| --- a/chrome/browser/extensions/api/storage/settings_backend.cc
|
| +++ b/chrome/browser/extensions/api/storage/sync_storage_backend.cc
|
| @@ -2,7 +2,7 @@
|
| // 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_backend.h"
|
| +#include "chrome/browser/extensions/api/storage/sync_storage_backend.h"
|
|
|
| #include "base/files/file_enumerator.h"
|
| #include "base/logging.h"
|
| @@ -16,16 +16,28 @@ using content::BrowserThread;
|
|
|
| namespace extensions {
|
|
|
| -SettingsBackend::SettingsBackend(
|
| +namespace {
|
| +
|
| +void AddAllSyncData(const std::string& extension_id,
|
| + const base::DictionaryValue& src,
|
| + syncer::ModelType type,
|
| + syncer::SyncDataList* dst) {
|
| + for (base::DictionaryValue::Iterator it(src); !it.IsAtEnd(); it.Advance()) {
|
| + dst->push_back(settings_sync_util::CreateData(
|
| + extension_id, it.key(), it.value(), type));
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +SyncStorageBackend::SyncStorageBackend(
|
| const scoped_refptr<SettingsStorageFactory>& storage_factory,
|
| const base::FilePath& base_path,
|
| - syncer::ModelType sync_type,
|
| - const syncer::SyncableService::StartSyncFlare& flare,
|
| const SettingsStorageQuotaEnforcer::Limits& quota,
|
| - const scoped_refptr<SettingsObserverList>& observers)
|
| - : storage_factory_(storage_factory),
|
| - base_path_(base_path),
|
| - quota_(quota),
|
| + const scoped_refptr<SettingsObserverList>& observers,
|
| + syncer::ModelType sync_type,
|
| + const syncer::SyncableService::StartSyncFlare& flare)
|
| + : SettingsBackend(storage_factory, base_path, quota),
|
| observers_(observers),
|
| sync_type_(sync_type),
|
| flare_(flare) {
|
| @@ -34,18 +46,15 @@ SettingsBackend::SettingsBackend(
|
| sync_type_ == syncer::APP_SETTINGS);
|
| }
|
|
|
| -SettingsBackend::~SettingsBackend() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| -}
|
| +SyncStorageBackend::~SyncStorageBackend() {}
|
|
|
| -ValueStore* SettingsBackend::GetStorage(
|
| - const std::string& extension_id) const {
|
| +ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| base::DictionaryValue empty;
|
| return GetOrCreateStorageWithSyncData(extension_id, empty);
|
| }
|
|
|
| -SyncableSettingsStorage* SettingsBackend::GetOrCreateStorageWithSyncData(
|
| +SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData(
|
| const std::string& extension_id,
|
| const base::DictionaryValue& sync_data) const {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| @@ -55,34 +64,26 @@ SyncableSettingsStorage* SettingsBackend::GetOrCreateStorageWithSyncData(
|
| return maybe_storage->second.get();
|
| }
|
|
|
| - ValueStore* storage = storage_factory_->Create(base_path_, extension_id);
|
| - CHECK(storage);
|
| + scoped_ptr<SettingsStorageQuotaEnforcer> storage =
|
| + CreateStorageForExtension(extension_id);
|
|
|
| // It's fine to create the quota enforcer underneath the sync layer, since
|
| // sync will only go ahead if each underlying storage operation succeeds.
|
| - storage = new SettingsStorageQuotaEnforcer(quota_, storage);
|
| -
|
| linked_ptr<SyncableSettingsStorage> syncable_storage(
|
| new SyncableSettingsStorage(
|
| - observers_,
|
| - extension_id,
|
| - storage,
|
| - sync_type_,
|
| - flare_));
|
| + observers_, extension_id, storage.release(), sync_type_, flare_));
|
| storage_objs_[extension_id] = syncable_storage;
|
|
|
| if (sync_processor_.get()) {
|
| - syncer::SyncError error =
|
| - syncable_storage->StartSyncing(
|
| - sync_data,
|
| - CreateSettingsSyncProcessor(extension_id).Pass());
|
| + syncer::SyncError error = syncable_storage->StartSyncing(
|
| + sync_data, CreateSettingsSyncProcessor(extension_id).Pass());
|
| if (error.IsSet())
|
| syncable_storage.get()->StopSyncing();
|
| }
|
| return syncable_storage.get();
|
| }
|
|
|
| -void SettingsBackend::DeleteStorage(const std::string& extension_id) {
|
| +void SyncStorageBackend::DeleteStorage(const std::string& extension_id) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
|
|
| // Clear settings when the extension is uninstalled. Leveldb implementations
|
| @@ -100,20 +101,25 @@ void SettingsBackend::DeleteStorage(const std::string& extension_id) {
|
| storage_objs_.erase(extension_id);
|
| }
|
|
|
| -std::set<std::string> SettingsBackend::GetKnownExtensionIDs() const {
|
| +syncer::SyncableService* SyncStorageBackend::GetAsSyncableService() {
|
| + return this;
|
| +}
|
| +
|
| +std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs() const {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| std::set<std::string> result;
|
|
|
| // Storage areas can be in-memory as well as on disk. |storage_objs_| will
|
| // contain all that are in-memory.
|
| for (StorageObjMap::iterator it = storage_objs_.begin();
|
| - it != storage_objs_.end(); ++it) {
|
| + it != storage_objs_.end();
|
| + ++it) {
|
| result.insert(it->first);
|
| }
|
|
|
| - // Leveldb databases are directories inside base_path_.
|
| + // Leveldb databases are directories inside base_path().
|
| base::FileEnumerator extension_dirs(
|
| - base_path_, false, base::FileEnumerator::DIRECTORIES);
|
| + base_path(), false, base::FileEnumerator::DIRECTORIES);
|
| while (!extension_dirs.Next().empty()) {
|
| base::FilePath extension_dir = extension_dirs.GetInfo().GetName();
|
| DCHECK(!extension_dir.IsAbsolute());
|
| @@ -127,24 +133,12 @@ std::set<std::string> SettingsBackend::GetKnownExtensionIDs() const {
|
| return result;
|
| }
|
|
|
| -static void AddAllSyncData(
|
| - const std::string& extension_id,
|
| - const base::DictionaryValue& src,
|
| - syncer::ModelType type,
|
| - syncer::SyncDataList* dst) {
|
| - for (base::DictionaryValue::Iterator it(src); !it.IsAtEnd(); it.Advance()) {
|
| - dst->push_back(settings_sync_util::CreateData(
|
| - extension_id, it.key(), it.value(), type));
|
| - }
|
| -}
|
| -
|
| -syncer::SyncDataList SettingsBackend::GetAllSyncData(
|
| - syncer::ModelType type) const {
|
| +syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type)
|
| + const {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| // Ignore the type, it's just for sanity checking; assume that whatever base
|
| // path we're constructed with is correct for the sync type.
|
| - DCHECK(type == syncer::EXTENSION_SETTINGS ||
|
| - type == syncer::APP_SETTINGS);
|
| + DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
|
|
|
| // For all extensions, get all their settings. This has the effect
|
| // of bringing in the entire state of extension settings in memory; sad.
|
| @@ -152,11 +146,13 @@ syncer::SyncDataList SettingsBackend::GetAllSyncData(
|
| std::set<std::string> known_extension_ids(GetKnownExtensionIDs());
|
|
|
| for (std::set<std::string>::const_iterator it = known_extension_ids.begin();
|
| - it != known_extension_ids.end(); ++it) {
|
| - ValueStore::ReadResult maybe_settings = GetStorage(*it)->Get();
|
| + it != known_extension_ids.end();
|
| + ++it) {
|
| + ValueStore::ReadResult maybe_settings =
|
| + GetOrCreateStorageWithSyncData(*it, base::DictionaryValue())->Get();
|
| if (maybe_settings->HasError()) {
|
| - LOG(WARNING) << "Failed to get settings for " << *it << ": " <<
|
| - maybe_settings->error().message;
|
| + LOG(WARNING) << "Failed to get settings for " << *it << ": "
|
| + << maybe_settings->error().message;
|
| continue;
|
| }
|
| AddAllSyncData(*it, maybe_settings->settings(), type, &all_sync_data);
|
| @@ -165,7 +161,7 @@ syncer::SyncDataList SettingsBackend::GetAllSyncData(
|
| return all_sync_data;
|
| }
|
|
|
| -syncer::SyncMergeResult SettingsBackend::MergeDataAndStartSyncing(
|
| +syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing(
|
| syncer::ModelType type,
|
| const syncer::SyncDataList& initial_sync_data,
|
| scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
|
| @@ -182,24 +178,27 @@ syncer::SyncMergeResult SettingsBackend::MergeDataAndStartSyncing(
|
| // Group the initial sync data by extension id.
|
| std::map<std::string, linked_ptr<base::DictionaryValue> > grouped_sync_data;
|
| for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin();
|
| - it != initial_sync_data.end(); ++it) {
|
| + it != initial_sync_data.end();
|
| + ++it) {
|
| SettingSyncData data(*it);
|
| linked_ptr<base::DictionaryValue> sync_data =
|
| grouped_sync_data[data.extension_id()];
|
| if (!sync_data.get()) {
|
| - sync_data = linked_ptr<base::DictionaryValue>(
|
| - new base::DictionaryValue());
|
| + sync_data =
|
| + linked_ptr<base::DictionaryValue>(new base::DictionaryValue());
|
| grouped_sync_data[data.extension_id()] = sync_data;
|
| }
|
| - DCHECK(!sync_data->HasKey(data.key())) <<
|
| - "Duplicate settings for " << data.extension_id() << "/" << data.key();
|
| + DCHECK(!sync_data->HasKey(data.key())) << "Duplicate settings for "
|
| + << data.extension_id() << "/"
|
| + << data.key();
|
| sync_data->SetWithoutPathExpansion(data.key(), data.value().DeepCopy());
|
| }
|
|
|
| // Start syncing all existing storage areas. Any storage areas created in
|
| // the future will start being synced as part of the creation process.
|
| for (StorageObjMap::iterator it = storage_objs_.begin();
|
| - it != storage_objs_.end(); ++it) {
|
| + it != storage_objs_.end();
|
| + ++it) {
|
| std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator
|
| maybe_sync_data = grouped_sync_data.find(it->first);
|
| syncer::SyncError error;
|
| @@ -211,8 +210,7 @@ syncer::SyncMergeResult SettingsBackend::MergeDataAndStartSyncing(
|
| } else {
|
| base::DictionaryValue empty;
|
| error = it->second->StartSyncing(
|
| - empty,
|
| - CreateSettingsSyncProcessor(it->first).Pass());
|
| + empty, CreateSettingsSyncProcessor(it->first).Pass());
|
| }
|
| if (error.IsSet())
|
| it->second->StopSyncing();
|
| @@ -222,14 +220,16 @@ syncer::SyncMergeResult SettingsBackend::MergeDataAndStartSyncing(
|
| // Under normal circumstances (i.e. not first-time sync) this will be all of
|
| // them.
|
| for (std::map<std::string, linked_ptr<base::DictionaryValue> >::iterator it =
|
| - grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) {
|
| + grouped_sync_data.begin();
|
| + it != grouped_sync_data.end();
|
| + ++it) {
|
| GetOrCreateStorageWithSyncData(it->first, *it->second);
|
| }
|
|
|
| return syncer::SyncMergeResult(type);
|
| }
|
|
|
| -syncer::SyncError SettingsBackend::ProcessSyncChanges(
|
| +syncer::SyncError SyncStorageBackend::ProcessSyncChanges(
|
| const tracked_objects::Location& from_here,
|
| const syncer::SyncChangeList& sync_changes) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| @@ -238,15 +238,18 @@ syncer::SyncError SettingsBackend::ProcessSyncChanges(
|
| // Group changes by extension, to pass all changes in a single method call.
|
| std::map<std::string, SettingSyncDataList> grouped_sync_data;
|
| for (syncer::SyncChangeList::const_iterator it = sync_changes.begin();
|
| - it != sync_changes.end(); ++it) {
|
| + it != sync_changes.end();
|
| + ++it) {
|
| SettingSyncData data(*it);
|
| grouped_sync_data[data.extension_id()].push_back(data);
|
| }
|
|
|
| // Create any storage areas that don't exist yet but have sync data.
|
| base::DictionaryValue empty;
|
| - for (std::map<std::string, SettingSyncDataList>::iterator
|
| - it = grouped_sync_data.begin(); it != grouped_sync_data.end(); ++it) {
|
| + for (std::map<std::string, SettingSyncDataList>::iterator it =
|
| + grouped_sync_data.begin();
|
| + it != grouped_sync_data.end();
|
| + ++it) {
|
| SyncableSettingsStorage* storage =
|
| GetOrCreateStorageWithSyncData(it->first, empty);
|
| syncer::SyncError error = storage->ProcessSyncChanges(it->second);
|
| @@ -257,14 +260,14 @@ syncer::SyncError SettingsBackend::ProcessSyncChanges(
|
| return syncer::SyncError();
|
| }
|
|
|
| -void SettingsBackend::StopSyncing(syncer::ModelType type) {
|
| +void SyncStorageBackend::StopSyncing(syncer::ModelType type) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| - DCHECK(type == syncer::EXTENSION_SETTINGS ||
|
| - type == syncer::APP_SETTINGS);
|
| + DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
|
| DCHECK_EQ(sync_type_, type);
|
|
|
| for (StorageObjMap::iterator it = storage_objs_.begin();
|
| - it != storage_objs_.end(); ++it) {
|
| + it != storage_objs_.end();
|
| + ++it) {
|
| // Some storage areas may have already stopped syncing if they had areas
|
| // and syncing was disabled, but StopSyncing is safe to call multiple times.
|
| it->second->StopSyncing();
|
| @@ -274,13 +277,12 @@ void SettingsBackend::StopSyncing(syncer::ModelType type) {
|
| sync_error_factory_.reset();
|
| }
|
|
|
| -scoped_ptr<SettingsSyncProcessor> SettingsBackend::CreateSettingsSyncProcessor(
|
| - const std::string& extension_id) const {
|
| +scoped_ptr<SettingsSyncProcessor>
|
| +SyncStorageBackend::CreateSettingsSyncProcessor(const std::string& extension_id)
|
| + const {
|
| CHECK(sync_processor_.get());
|
| - return scoped_ptr<SettingsSyncProcessor>(
|
| - new SettingsSyncProcessor(extension_id,
|
| - sync_type_,
|
| - sync_processor_.get()));
|
| + return scoped_ptr<SettingsSyncProcessor>(new SettingsSyncProcessor(
|
| + extension_id, sync_type_, sync_processor_.get()));
|
| }
|
|
|
| } // namespace extensions
|
|
|