| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/storage/sync_storage_backend.h" | 5 #include "chrome/browser/extensions/api/storage/sync_storage_backend.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" | 11 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" |
| 12 #include "chrome/browser/extensions/api/storage/settings_sync_util.h" | 12 #include "chrome/browser/extensions/api/storage/settings_sync_util.h" |
| 13 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h" | 13 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h" |
| 14 #include "components/sync/model/sync_error_factory.h" | 14 #include "components/sync/model/sync_error_factory.h" |
| 15 #include "content/public/browser/browser_thread.h" | 15 #include "extensions/browser/api/storage/backend_task_runner.h" |
| 16 | |
| 17 using content::BrowserThread; | |
| 18 | 16 |
| 19 namespace extensions { | 17 namespace extensions { |
| 20 | 18 |
| 21 namespace { | 19 namespace { |
| 22 | 20 |
| 23 void AddAllSyncData(const std::string& extension_id, | 21 void AddAllSyncData(const std::string& extension_id, |
| 24 const base::DictionaryValue& src, | 22 const base::DictionaryValue& src, |
| 25 syncer::ModelType type, | 23 syncer::ModelType type, |
| 26 syncer::SyncDataList* dst) { | 24 syncer::SyncDataList* dst) { |
| 27 for (base::DictionaryValue::Iterator it(src); !it.IsAtEnd(); it.Advance()) { | 25 for (base::DictionaryValue::Iterator it(src); !it.IsAtEnd(); it.Advance()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 52 const scoped_refptr<ValueStoreFactory>& storage_factory, | 50 const scoped_refptr<ValueStoreFactory>& storage_factory, |
| 53 const SettingsStorageQuotaEnforcer::Limits& quota, | 51 const SettingsStorageQuotaEnforcer::Limits& quota, |
| 54 const scoped_refptr<SettingsObserverList>& observers, | 52 const scoped_refptr<SettingsObserverList>& observers, |
| 55 syncer::ModelType sync_type, | 53 syncer::ModelType sync_type, |
| 56 const syncer::SyncableService::StartSyncFlare& flare) | 54 const syncer::SyncableService::StartSyncFlare& flare) |
| 57 : storage_factory_(storage_factory), | 55 : storage_factory_(storage_factory), |
| 58 quota_(quota), | 56 quota_(quota), |
| 59 observers_(observers), | 57 observers_(observers), |
| 60 sync_type_(sync_type), | 58 sync_type_(sync_type), |
| 61 flare_(flare) { | 59 flare_(flare) { |
| 62 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 60 DCHECK(IsOnBackendSequence()); |
| 63 DCHECK(sync_type_ == syncer::EXTENSION_SETTINGS || | 61 DCHECK(sync_type_ == syncer::EXTENSION_SETTINGS || |
| 64 sync_type_ == syncer::APP_SETTINGS); | 62 sync_type_ == syncer::APP_SETTINGS); |
| 65 } | 63 } |
| 66 | 64 |
| 67 SyncStorageBackend::~SyncStorageBackend() {} | 65 SyncStorageBackend::~SyncStorageBackend() {} |
| 68 | 66 |
| 69 ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) { | 67 ValueStore* SyncStorageBackend::GetStorage(const std::string& extension_id) { |
| 70 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 68 DCHECK(IsOnBackendSequence()); |
| 71 return GetOrCreateStorageWithSyncData(extension_id, EmptyDictionaryValue()); | 69 return GetOrCreateStorageWithSyncData(extension_id, EmptyDictionaryValue()); |
| 72 } | 70 } |
| 73 | 71 |
| 74 SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData( | 72 SyncableSettingsStorage* SyncStorageBackend::GetOrCreateStorageWithSyncData( |
| 75 const std::string& extension_id, | 73 const std::string& extension_id, |
| 76 std::unique_ptr<base::DictionaryValue> sync_data) const { | 74 std::unique_ptr<base::DictionaryValue> sync_data) const { |
| 77 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 75 DCHECK(IsOnBackendSequence()); |
| 78 | 76 |
| 79 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); | 77 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); |
| 80 if (maybe_storage != storage_objs_.end()) { | 78 if (maybe_storage != storage_objs_.end()) { |
| 81 return maybe_storage->second.get(); | 79 return maybe_storage->second.get(); |
| 82 } | 80 } |
| 83 | 81 |
| 84 std::unique_ptr<SettingsStorageQuotaEnforcer> settings_storage( | 82 std::unique_ptr<SettingsStorageQuotaEnforcer> settings_storage( |
| 85 new SettingsStorageQuotaEnforcer( | 83 new SettingsStorageQuotaEnforcer( |
| 86 quota_, storage_factory_->CreateSettingsStore( | 84 quota_, storage_factory_->CreateSettingsStore( |
| 87 settings_namespace::SYNC, ToFactoryModelType(sync_type_), | 85 settings_namespace::SYNC, ToFactoryModelType(sync_type_), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 99 if (sync_processor_.get()) { | 97 if (sync_processor_.get()) { |
| 100 syncer::SyncError error = raw_syncable_storage->StartSyncing( | 98 syncer::SyncError error = raw_syncable_storage->StartSyncing( |
| 101 std::move(sync_data), CreateSettingsSyncProcessor(extension_id)); | 99 std::move(sync_data), CreateSettingsSyncProcessor(extension_id)); |
| 102 if (error.IsSet()) | 100 if (error.IsSet()) |
| 103 raw_syncable_storage->StopSyncing(); | 101 raw_syncable_storage->StopSyncing(); |
| 104 } | 102 } |
| 105 return raw_syncable_storage; | 103 return raw_syncable_storage; |
| 106 } | 104 } |
| 107 | 105 |
| 108 void SyncStorageBackend::DeleteStorage(const std::string& extension_id) { | 106 void SyncStorageBackend::DeleteStorage(const std::string& extension_id) { |
| 109 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 107 DCHECK(IsOnBackendSequence()); |
| 110 | 108 |
| 111 // Clear settings when the extension is uninstalled. Leveldb implementations | 109 // Clear settings when the extension is uninstalled. Leveldb implementations |
| 112 // will also delete the database from disk when the object is destroyed as a | 110 // will also delete the database from disk when the object is destroyed as a |
| 113 // result of being removed from |storage_objs_|. | 111 // result of being removed from |storage_objs_|. |
| 114 // | 112 // |
| 115 // TODO(kalman): always GetStorage here (rather than only clearing if it | 113 // TODO(kalman): always GetStorage here (rather than only clearing if it |
| 116 // exists) since the storage area may have been unloaded, but we still want | 114 // exists) since the storage area may have been unloaded, but we still want |
| 117 // to clear the data from disk. | 115 // to clear the data from disk. |
| 118 // However, this triggers http://crbug.com/111072. | 116 // However, this triggers http://crbug.com/111072. |
| 119 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); | 117 StorageObjMap::iterator maybe_storage = storage_objs_.find(extension_id); |
| 120 if (maybe_storage == storage_objs_.end()) | 118 if (maybe_storage == storage_objs_.end()) |
| 121 return; | 119 return; |
| 122 maybe_storage->second->Clear(); | 120 maybe_storage->second->Clear(); |
| 123 storage_objs_.erase(extension_id); | 121 storage_objs_.erase(extension_id); |
| 124 } | 122 } |
| 125 | 123 |
| 126 std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs( | 124 std::set<std::string> SyncStorageBackend::GetKnownExtensionIDs( |
| 127 ValueStoreFactory::ModelType model_type) const { | 125 ValueStoreFactory::ModelType model_type) const { |
| 128 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 126 DCHECK(IsOnBackendSequence()); |
| 129 std::set<std::string> result; | 127 std::set<std::string> result; |
| 130 | 128 |
| 131 // Storage areas can be in-memory as well as on disk. |storage_objs_| will | 129 // Storage areas can be in-memory as well as on disk. |storage_objs_| will |
| 132 // contain all that are in-memory. | 130 // contain all that are in-memory. |
| 133 for (const auto& storage_obj : storage_objs_) { | 131 for (const auto& storage_obj : storage_objs_) { |
| 134 result.insert(storage_obj.first); | 132 result.insert(storage_obj.first); |
| 135 } | 133 } |
| 136 | 134 |
| 137 std::set<std::string> disk_ids = storage_factory_->GetKnownExtensionIDs( | 135 std::set<std::string> disk_ids = storage_factory_->GetKnownExtensionIDs( |
| 138 settings_namespace::SYNC, model_type); | 136 settings_namespace::SYNC, model_type); |
| 139 result.insert(disk_ids.begin(), disk_ids.end()); | 137 result.insert(disk_ids.begin(), disk_ids.end()); |
| 140 | 138 |
| 141 return result; | 139 return result; |
| 142 } | 140 } |
| 143 | 141 |
| 144 syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type) | 142 syncer::SyncDataList SyncStorageBackend::GetAllSyncData(syncer::ModelType type) |
| 145 const { | 143 const { |
| 146 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 144 DCHECK(IsOnBackendSequence()); |
| 147 // For all extensions, get all their settings. This has the effect | 145 // For all extensions, get all their settings. This has the effect |
| 148 // of bringing in the entire state of extension settings in memory; sad. | 146 // of bringing in the entire state of extension settings in memory; sad. |
| 149 syncer::SyncDataList all_sync_data; | 147 syncer::SyncDataList all_sync_data; |
| 150 std::set<std::string> known_extension_ids( | 148 std::set<std::string> known_extension_ids( |
| 151 GetKnownExtensionIDs(ToFactoryModelType(type))); | 149 GetKnownExtensionIDs(ToFactoryModelType(type))); |
| 152 | 150 |
| 153 for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); | 151 for (std::set<std::string>::const_iterator it = known_extension_ids.begin(); |
| 154 it != known_extension_ids.end(); | 152 it != known_extension_ids.end(); |
| 155 ++it) { | 153 ++it) { |
| 156 ValueStore::ReadResult maybe_settings = | 154 ValueStore::ReadResult maybe_settings = |
| 157 GetOrCreateStorageWithSyncData(*it, EmptyDictionaryValue())->Get(); | 155 GetOrCreateStorageWithSyncData(*it, EmptyDictionaryValue())->Get(); |
| 158 if (!maybe_settings->status().ok()) { | 156 if (!maybe_settings->status().ok()) { |
| 159 LOG(WARNING) << "Failed to get settings for " << *it << ": " | 157 LOG(WARNING) << "Failed to get settings for " << *it << ": " |
| 160 << maybe_settings->status().message; | 158 << maybe_settings->status().message; |
| 161 continue; | 159 continue; |
| 162 } | 160 } |
| 163 AddAllSyncData(*it, maybe_settings->settings(), type, &all_sync_data); | 161 AddAllSyncData(*it, maybe_settings->settings(), type, &all_sync_data); |
| 164 } | 162 } |
| 165 | 163 |
| 166 return all_sync_data; | 164 return all_sync_data; |
| 167 } | 165 } |
| 168 | 166 |
| 169 syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing( | 167 syncer::SyncMergeResult SyncStorageBackend::MergeDataAndStartSyncing( |
| 170 syncer::ModelType type, | 168 syncer::ModelType type, |
| 171 const syncer::SyncDataList& initial_sync_data, | 169 const syncer::SyncDataList& initial_sync_data, |
| 172 std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, | 170 std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, |
| 173 std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) { | 171 std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) { |
| 174 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 172 DCHECK(IsOnBackendSequence()); |
| 175 DCHECK_EQ(sync_type_, type); | 173 DCHECK_EQ(sync_type_, type); |
| 176 DCHECK(!sync_processor_.get()); | 174 DCHECK(!sync_processor_.get()); |
| 177 DCHECK(sync_processor.get()); | 175 DCHECK(sync_processor.get()); |
| 178 DCHECK(sync_error_factory.get()); | 176 DCHECK(sync_error_factory.get()); |
| 179 | 177 |
| 180 sync_processor_ = std::move(sync_processor); | 178 sync_processor_ = std::move(sync_processor); |
| 181 sync_error_factory_ = std::move(sync_error_factory); | 179 sync_error_factory_ = std::move(sync_error_factory); |
| 182 | 180 |
| 183 // Group the initial sync data by extension id. | 181 // Group the initial sync data by extension id. |
| 184 // The raw pointers are safe because ownership of each item is passed to | 182 // The raw pointers are safe because ownership of each item is passed to |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 for (const auto& group : grouped_sync_data) { | 222 for (const auto& group : grouped_sync_data) { |
| 225 GetOrCreateStorageWithSyncData(group.first, base::WrapUnique(group.second)); | 223 GetOrCreateStorageWithSyncData(group.first, base::WrapUnique(group.second)); |
| 226 } | 224 } |
| 227 | 225 |
| 228 return syncer::SyncMergeResult(type); | 226 return syncer::SyncMergeResult(type); |
| 229 } | 227 } |
| 230 | 228 |
| 231 syncer::SyncError SyncStorageBackend::ProcessSyncChanges( | 229 syncer::SyncError SyncStorageBackend::ProcessSyncChanges( |
| 232 const tracked_objects::Location& from_here, | 230 const tracked_objects::Location& from_here, |
| 233 const syncer::SyncChangeList& sync_changes) { | 231 const syncer::SyncChangeList& sync_changes) { |
| 234 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 232 DCHECK(IsOnBackendSequence()); |
| 235 DCHECK(sync_processor_.get()); | 233 DCHECK(sync_processor_.get()); |
| 236 | 234 |
| 237 // Group changes by extension, to pass all changes in a single method call. | 235 // Group changes by extension, to pass all changes in a single method call. |
| 238 // The raw pointers are safe because ownership of each item is passed to | 236 // The raw pointers are safe because ownership of each item is passed to |
| 239 // storage->ProcessSyncChanges. | 237 // storage->ProcessSyncChanges. |
| 240 std::map<std::string, SettingSyncDataList*> grouped_sync_data; | 238 std::map<std::string, SettingSyncDataList*> grouped_sync_data; |
| 241 | 239 |
| 242 for (const syncer::SyncChange& change : sync_changes) { | 240 for (const syncer::SyncChange& change : sync_changes) { |
| 243 std::unique_ptr<SettingSyncData> data(new SettingSyncData(change)); | 241 std::unique_ptr<SettingSyncData> data(new SettingSyncData(change)); |
| 244 SettingSyncDataList*& group = grouped_sync_data[data->extension_id()]; | 242 SettingSyncDataList*& group = grouped_sync_data[data->extension_id()]; |
| 245 if (!group) | 243 if (!group) |
| 246 group = new SettingSyncDataList(); | 244 group = new SettingSyncDataList(); |
| 247 group->push_back(std::move(data)); | 245 group->push_back(std::move(data)); |
| 248 } | 246 } |
| 249 | 247 |
| 250 // Create any storage areas that don't exist yet but have sync data. | 248 // Create any storage areas that don't exist yet but have sync data. |
| 251 for (const auto& group : grouped_sync_data) { | 249 for (const auto& group : grouped_sync_data) { |
| 252 SyncableSettingsStorage* storage = | 250 SyncableSettingsStorage* storage = |
| 253 GetOrCreateStorageWithSyncData(group.first, EmptyDictionaryValue()); | 251 GetOrCreateStorageWithSyncData(group.first, EmptyDictionaryValue()); |
| 254 syncer::SyncError error = | 252 syncer::SyncError error = |
| 255 storage->ProcessSyncChanges(base::WrapUnique(group.second)); | 253 storage->ProcessSyncChanges(base::WrapUnique(group.second)); |
| 256 if (error.IsSet()) | 254 if (error.IsSet()) |
| 257 storage->StopSyncing(); | 255 storage->StopSyncing(); |
| 258 } | 256 } |
| 259 | 257 |
| 260 return syncer::SyncError(); | 258 return syncer::SyncError(); |
| 261 } | 259 } |
| 262 | 260 |
| 263 void SyncStorageBackend::StopSyncing(syncer::ModelType type) { | 261 void SyncStorageBackend::StopSyncing(syncer::ModelType type) { |
| 264 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 262 DCHECK(IsOnBackendSequence()); |
| 265 DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS); | 263 DCHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS); |
| 266 DCHECK_EQ(sync_type_, type); | 264 DCHECK_EQ(sync_type_, type); |
| 267 | 265 |
| 268 for (const auto& storage_obj : storage_objs_) { | 266 for (const auto& storage_obj : storage_objs_) { |
| 269 // Some storage areas may have already stopped syncing if they had areas | 267 // Some storage areas may have already stopped syncing if they had areas |
| 270 // and syncing was disabled, but StopSyncing is safe to call multiple times. | 268 // and syncing was disabled, but StopSyncing is safe to call multiple times. |
| 271 storage_obj.second->StopSyncing(); | 269 storage_obj.second->StopSyncing(); |
| 272 } | 270 } |
| 273 | 271 |
| 274 sync_processor_.reset(); | 272 sync_processor_.reset(); |
| 275 sync_error_factory_.reset(); | 273 sync_error_factory_.reset(); |
| 276 } | 274 } |
| 277 | 275 |
| 278 std::unique_ptr<SettingsSyncProcessor> | 276 std::unique_ptr<SettingsSyncProcessor> |
| 279 SyncStorageBackend::CreateSettingsSyncProcessor( | 277 SyncStorageBackend::CreateSettingsSyncProcessor( |
| 280 const std::string& extension_id) const { | 278 const std::string& extension_id) const { |
| 281 CHECK(sync_processor_.get()); | 279 CHECK(sync_processor_.get()); |
| 282 return std::unique_ptr<SettingsSyncProcessor>(new SettingsSyncProcessor( | 280 return std::unique_ptr<SettingsSyncProcessor>(new SettingsSyncProcessor( |
| 283 extension_id, sync_type_, sync_processor_.get())); | 281 extension_id, sync_type_, sync_processor_.get())); |
| 284 } | 282 } |
| 285 | 283 |
| 286 } // namespace extensions | 284 } // namespace extensions |
| OLD | NEW |