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 |