| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/syncable_settings_storage.h" | 5 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" | 10 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 // Tell sync to try and start soon, because syncable changes to sync_type_ | 146 // Tell sync to try and start soon, because syncable changes to sync_type_ |
| 147 // have started happening. This will cause sync to call us back | 147 // have started happening. This will cause sync to call us back |
| 148 // asynchronously via StartSyncing(...) as soon as possible. | 148 // asynchronously via StartSyncing(...) as soon as possible. |
| 149 flare_.Run(sync_type_); | 149 flare_.Run(sync_type_); |
| 150 } | 150 } |
| 151 } | 151 } |
| 152 | 152 |
| 153 // Sync-related methods. | 153 // Sync-related methods. |
| 154 | 154 |
| 155 syncer::SyncError SyncableSettingsStorage::StartSyncing( | 155 syncer::SyncError SyncableSettingsStorage::StartSyncing( |
| 156 scoped_ptr<base::DictionaryValue> sync_state, | 156 std::unique_ptr<base::DictionaryValue> sync_state, |
| 157 scoped_ptr<SettingsSyncProcessor> sync_processor) { | 157 std::unique_ptr<SettingsSyncProcessor> sync_processor) { |
| 158 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 158 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 159 DCHECK(sync_state); | 159 DCHECK(sync_state); |
| 160 DCHECK(!sync_processor_.get()); | 160 DCHECK(!sync_processor_.get()); |
| 161 | 161 |
| 162 sync_processor_ = std::move(sync_processor); | 162 sync_processor_ = std::move(sync_processor); |
| 163 sync_processor_->Init(*sync_state); | 163 sync_processor_->Init(*sync_state); |
| 164 | 164 |
| 165 ReadResult maybe_settings = delegate_->Get(); | 165 ReadResult maybe_settings = delegate_->Get(); |
| 166 if (!maybe_settings->status().ok()) { | 166 if (!maybe_settings->status().ok()) { |
| 167 return syncer::SyncError( | 167 return syncer::SyncError( |
| 168 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 168 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 169 base::StringPrintf("Failed to get settings: %s", | 169 base::StringPrintf("Failed to get settings: %s", |
| 170 maybe_settings->status().message.c_str()), | 170 maybe_settings->status().message.c_str()), |
| 171 sync_processor_->type()); | 171 sync_processor_->type()); |
| 172 } | 172 } |
| 173 | 173 |
| 174 scoped_ptr<base::DictionaryValue> current_settings = | 174 std::unique_ptr<base::DictionaryValue> current_settings = |
| 175 maybe_settings->PassSettings(); | 175 maybe_settings->PassSettings(); |
| 176 return sync_state->empty() | 176 return sync_state->empty() |
| 177 ? SendLocalSettingsToSync(std::move(current_settings)) | 177 ? SendLocalSettingsToSync(std::move(current_settings)) |
| 178 : OverwriteLocalSettingsWithSync(std::move(sync_state), | 178 : OverwriteLocalSettingsWithSync(std::move(sync_state), |
| 179 std::move(current_settings)); | 179 std::move(current_settings)); |
| 180 } | 180 } |
| 181 | 181 |
| 182 syncer::SyncError SyncableSettingsStorage::SendLocalSettingsToSync( | 182 syncer::SyncError SyncableSettingsStorage::SendLocalSettingsToSync( |
| 183 scoped_ptr<base::DictionaryValue> local_state) { | 183 std::unique_ptr<base::DictionaryValue> local_state) { |
| 184 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 184 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 185 | 185 |
| 186 if (local_state->empty()) | 186 if (local_state->empty()) |
| 187 return syncer::SyncError(); | 187 return syncer::SyncError(); |
| 188 | 188 |
| 189 // Transform the current settings into a list of sync changes. | 189 // Transform the current settings into a list of sync changes. |
| 190 ValueStoreChangeList changes; | 190 ValueStoreChangeList changes; |
| 191 while (!local_state->empty()) { | 191 while (!local_state->empty()) { |
| 192 // It's not possible to iterate over a DictionaryValue and modify it at the | 192 // It's not possible to iterate over a DictionaryValue and modify it at the |
| 193 // same time, so hack around that restriction. | 193 // same time, so hack around that restriction. |
| 194 std::string key = base::DictionaryValue::Iterator(*local_state).key(); | 194 std::string key = base::DictionaryValue::Iterator(*local_state).key(); |
| 195 scoped_ptr<base::Value> value; | 195 std::unique_ptr<base::Value> value; |
| 196 local_state->RemoveWithoutPathExpansion(key, &value); | 196 local_state->RemoveWithoutPathExpansion(key, &value); |
| 197 changes.push_back(ValueStoreChange(key, nullptr, value.release())); | 197 changes.push_back(ValueStoreChange(key, nullptr, value.release())); |
| 198 } | 198 } |
| 199 | 199 |
| 200 syncer::SyncError error = sync_processor_->SendChanges(changes); | 200 syncer::SyncError error = sync_processor_->SendChanges(changes); |
| 201 if (error.IsSet()) | 201 if (error.IsSet()) |
| 202 StopSyncing(); | 202 StopSyncing(); |
| 203 return error; | 203 return error; |
| 204 } | 204 } |
| 205 | 205 |
| 206 syncer::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync( | 206 syncer::SyncError SyncableSettingsStorage::OverwriteLocalSettingsWithSync( |
| 207 scoped_ptr<base::DictionaryValue> sync_state, | 207 std::unique_ptr<base::DictionaryValue> sync_state, |
| 208 scoped_ptr<base::DictionaryValue> local_state) { | 208 std::unique_ptr<base::DictionaryValue> local_state) { |
| 209 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 209 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 210 // This is implemented by building up a list of sync changes then sending | 210 // This is implemented by building up a list of sync changes then sending |
| 211 // those to ProcessSyncChanges. This generates events like onStorageChanged. | 211 // those to ProcessSyncChanges. This generates events like onStorageChanged. |
| 212 scoped_ptr<SettingSyncDataList> changes(new SettingSyncDataList()); | 212 std::unique_ptr<SettingSyncDataList> changes(new SettingSyncDataList()); |
| 213 | 213 |
| 214 for (base::DictionaryValue::Iterator it(*local_state); !it.IsAtEnd(); | 214 for (base::DictionaryValue::Iterator it(*local_state); !it.IsAtEnd(); |
| 215 it.Advance()) { | 215 it.Advance()) { |
| 216 scoped_ptr<base::Value> sync_value; | 216 std::unique_ptr<base::Value> sync_value; |
| 217 if (sync_state->RemoveWithoutPathExpansion(it.key(), &sync_value)) { | 217 if (sync_state->RemoveWithoutPathExpansion(it.key(), &sync_value)) { |
| 218 if (sync_value->Equals(&it.value())) { | 218 if (sync_value->Equals(&it.value())) { |
| 219 // Sync and local values are the same, no changes to send. | 219 // Sync and local values are the same, no changes to send. |
| 220 } else { | 220 } else { |
| 221 // Sync value is different, update local setting with new value. | 221 // Sync value is different, update local setting with new value. |
| 222 changes->push_back(new SettingSyncData( | 222 changes->push_back(new SettingSyncData( |
| 223 syncer::SyncChange::ACTION_UPDATE, extension_id_, it.key(), | 223 syncer::SyncChange::ACTION_UPDATE, extension_id_, it.key(), |
| 224 std::move(sync_value))); | 224 std::move(sync_value))); |
| 225 } | 225 } |
| 226 } else { | 226 } else { |
| 227 // Not synced, delete local setting. | 227 // Not synced, delete local setting. |
| 228 changes->push_back(new SettingSyncData( | 228 changes->push_back(new SettingSyncData( |
| 229 syncer::SyncChange::ACTION_DELETE, extension_id_, it.key(), | 229 syncer::SyncChange::ACTION_DELETE, extension_id_, it.key(), |
| 230 scoped_ptr<base::Value>(new base::DictionaryValue()))); | 230 std::unique_ptr<base::Value>(new base::DictionaryValue()))); |
| 231 } | 231 } |
| 232 } | 232 } |
| 233 | 233 |
| 234 // Add all new settings to local settings. | 234 // Add all new settings to local settings. |
| 235 while (!sync_state->empty()) { | 235 while (!sync_state->empty()) { |
| 236 // It's not possible to iterate over a DictionaryValue and modify it at the | 236 // It's not possible to iterate over a DictionaryValue and modify it at the |
| 237 // same time, so hack around that restriction. | 237 // same time, so hack around that restriction. |
| 238 std::string key = base::DictionaryValue::Iterator(*sync_state).key(); | 238 std::string key = base::DictionaryValue::Iterator(*sync_state).key(); |
| 239 scoped_ptr<base::Value> value; | 239 std::unique_ptr<base::Value> value; |
| 240 CHECK(sync_state->RemoveWithoutPathExpansion(key, &value)); | 240 CHECK(sync_state->RemoveWithoutPathExpansion(key, &value)); |
| 241 changes->push_back(new SettingSyncData( | 241 changes->push_back(new SettingSyncData( |
| 242 syncer::SyncChange::ACTION_ADD, extension_id_, key, std::move(value))); | 242 syncer::SyncChange::ACTION_ADD, extension_id_, key, std::move(value))); |
| 243 } | 243 } |
| 244 | 244 |
| 245 if (changes->empty()) | 245 if (changes->empty()) |
| 246 return syncer::SyncError(); | 246 return syncer::SyncError(); |
| 247 return ProcessSyncChanges(std::move(changes)); | 247 return ProcessSyncChanges(std::move(changes)); |
| 248 } | 248 } |
| 249 | 249 |
| 250 void SyncableSettingsStorage::StopSyncing() { | 250 void SyncableSettingsStorage::StopSyncing() { |
| 251 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 251 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 252 sync_processor_.reset(); | 252 sync_processor_.reset(); |
| 253 } | 253 } |
| 254 | 254 |
| 255 syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( | 255 syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( |
| 256 scoped_ptr<SettingSyncDataList> sync_changes) { | 256 std::unique_ptr<SettingSyncDataList> sync_changes) { |
| 257 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 257 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 258 DCHECK(!sync_changes->empty()) << "No sync changes for " << extension_id_; | 258 DCHECK(!sync_changes->empty()) << "No sync changes for " << extension_id_; |
| 259 | 259 |
| 260 if (!sync_processor_.get()) { | 260 if (!sync_processor_.get()) { |
| 261 return syncer::SyncError( | 261 return syncer::SyncError( |
| 262 FROM_HERE, | 262 FROM_HERE, |
| 263 syncer::SyncError::DATATYPE_ERROR, | 263 syncer::SyncError::DATATYPE_ERROR, |
| 264 std::string("Sync is inactive for ") + extension_id_, | 264 std::string("Sync is inactive for ") + extension_id_, |
| 265 syncer::UNSPECIFIED); | 265 syncer::UNSPECIFIED); |
| 266 } | 266 } |
| 267 | 267 |
| 268 std::vector<syncer::SyncError> errors; | 268 std::vector<syncer::SyncError> errors; |
| 269 ValueStoreChangeList changes; | 269 ValueStoreChangeList changes; |
| 270 | 270 |
| 271 for (SettingSyncDataList::iterator it = sync_changes->begin(); | 271 for (SettingSyncDataList::iterator it = sync_changes->begin(); |
| 272 it != sync_changes->end(); ++it) { | 272 it != sync_changes->end(); ++it) { |
| 273 DCHECK_EQ(extension_id_, (*it)->extension_id()); | 273 DCHECK_EQ(extension_id_, (*it)->extension_id()); |
| 274 const std::string& key = (*it)->key(); | 274 const std::string& key = (*it)->key(); |
| 275 scoped_ptr<base::Value> change_value = (*it)->PassValue(); | 275 std::unique_ptr<base::Value> change_value = (*it)->PassValue(); |
| 276 | 276 |
| 277 scoped_ptr<base::Value> current_value; | 277 std::unique_ptr<base::Value> current_value; |
| 278 { | 278 { |
| 279 ReadResult maybe_settings = Get(key); | 279 ReadResult maybe_settings = Get(key); |
| 280 if (!maybe_settings->status().ok()) { | 280 if (!maybe_settings->status().ok()) { |
| 281 errors.push_back(syncer::SyncError( | 281 errors.push_back(syncer::SyncError( |
| 282 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 282 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 283 base::StringPrintf("Error getting current sync state for %s/%s: %s", | 283 base::StringPrintf("Error getting current sync state for %s/%s: %s", |
| 284 extension_id_.c_str(), key.c_str(), | 284 extension_id_.c_str(), key.c_str(), |
| 285 maybe_settings->status().message.c_str()), | 285 maybe_settings->status().message.c_str()), |
| 286 sync_processor_->type())); | 286 sync_processor_->type())); |
| 287 continue; | 287 continue; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 396 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 397 base::StringPrintf("Error pushing sync remove to local settings: %s", | 397 base::StringPrintf("Error pushing sync remove to local settings: %s", |
| 398 result->status().message.c_str()), | 398 result->status().message.c_str()), |
| 399 sync_processor_->type()); | 399 sync_processor_->type()); |
| 400 } | 400 } |
| 401 changes->push_back(ValueStoreChange(key, old_value, NULL)); | 401 changes->push_back(ValueStoreChange(key, old_value, NULL)); |
| 402 return syncer::SyncError(); | 402 return syncer::SyncError(); |
| 403 } | 403 } |
| 404 | 404 |
| 405 } // namespace extensions | 405 } // namespace extensions |
| OLD | NEW |