- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / storage / settings_sync_processor.cc
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/storage/settings_namespace.h"
6 #include "chrome/browser/extensions/api/storage/settings_sync_processor.h"
7 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "sync/api/sync_change_processor.h"
10 #include "sync/api/sync_data.h"
11 #include "sync/protocol/extension_setting_specifics.pb.h"
12
13 using content::BrowserThread;
14
15 namespace extensions {
16
17 SettingsSyncProcessor::SettingsSyncProcessor(
18     const std::string& extension_id,
19     syncer::ModelType type,
20     syncer::SyncChangeProcessor* sync_processor)
21     : extension_id_(extension_id),
22       type_(type),
23       sync_processor_(sync_processor),
24       initialized_(false) {
25   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
26   CHECK(type == syncer::EXTENSION_SETTINGS || type == syncer::APP_SETTINGS);
27   CHECK(sync_processor);
28 }
29
30 SettingsSyncProcessor::~SettingsSyncProcessor() {
31   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
32 }
33
34 void SettingsSyncProcessor::Init(const base::DictionaryValue& initial_state) {
35   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
36   CHECK(!initialized_) << "Init called multiple times";
37
38   for (base::DictionaryValue::Iterator i(initial_state); !i.IsAtEnd();
39        i.Advance())
40     synced_keys_.insert(i.key());
41
42   initialized_ = true;
43 }
44
45 syncer::SyncError SettingsSyncProcessor::SendChanges(
46     const ValueStoreChangeList& changes) {
47   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
48   CHECK(initialized_) << "Init not called";
49
50   syncer::SyncChangeList sync_changes;
51   std::set<std::string> added_keys;
52   std::set<std::string> deleted_keys;
53
54   for (ValueStoreChangeList::const_iterator i = changes.begin();
55       i != changes.end(); ++i) {
56     const std::string& key = i->key();
57     const Value* value = i->new_value();
58     if (value) {
59       if (synced_keys_.count(key)) {
60         // New value, key is synced; send ACTION_UPDATE.
61         sync_changes.push_back(settings_sync_util::CreateUpdate(
62             extension_id_, key, *value, type_));
63       } else {
64         // New value, key is not synced; send ACTION_ADD.
65         sync_changes.push_back(settings_sync_util::CreateAdd(
66             extension_id_, key, *value, type_));
67         added_keys.insert(key);
68       }
69     } else {
70       if (synced_keys_.count(key)) {
71         // Clearing value, key is synced; send ACTION_DELETE.
72         sync_changes.push_back(settings_sync_util::CreateDelete(
73             extension_id_, key, type_));
74         deleted_keys.insert(key);
75       } else {
76         LOG(WARNING) << "Deleted " << key << " but not in synced_keys_";
77       }
78     }
79   }
80
81   if (sync_changes.empty())
82     return syncer::SyncError();
83
84   syncer::SyncError error =
85       sync_processor_->ProcessSyncChanges(FROM_HERE, sync_changes);
86   if (error.IsSet())
87     return error;
88
89   synced_keys_.insert(added_keys.begin(), added_keys.end());
90   for (std::set<std::string>::iterator i = deleted_keys.begin();
91       i != deleted_keys.end(); ++i) {
92     synced_keys_.erase(*i);
93   }
94
95   return syncer::SyncError();
96 }
97
98 void SettingsSyncProcessor::NotifyChanges(const ValueStoreChangeList& changes) {
99   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
100   CHECK(initialized_) << "Init not called";
101
102   for (ValueStoreChangeList::const_iterator i = changes.begin();
103       i != changes.end(); ++i) {
104     if (i->new_value())
105       synced_keys_.insert(i->key());
106     else
107       synced_keys_.erase(i->key());
108   }
109 }
110
111 }  // namespace extensions