Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: chrome/browser/sync/glue/extension_sync.cc

Issue 7564037: Apps/Extensions Sync refactoring -- delete most of the old glue, implement new sync API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Release build warning :-/ Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/sync/glue/extension_sync.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "base/tracked.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_sync_data.h"
13 #include "chrome/browser/sync/glue/extension_sync_traits.h"
14 #include "chrome/browser/sync/glue/extension_util.h"
15 #include "chrome/browser/sync/internal_api/read_node.h"
16 #include "chrome/browser/sync/internal_api/read_transaction.h"
17 #include "chrome/browser/sync/internal_api/write_node.h"
18 #include "chrome/browser/sync/internal_api/write_transaction.h"
19 #include "chrome/browser/sync/protocol/extension_specifics.pb.h"
20
21 namespace browser_sync {
22
23 bool RootNodeHasChildren(const char* tag,
24 sync_api::UserShare* user_share,
25 bool* has_children) {
26 CHECK(has_children);
27 *has_children = false;
28 sync_api::ReadTransaction trans(FROM_HERE, user_share);
29 sync_api::ReadNode node(&trans);
30 if (!node.InitByTagLookup(tag)) {
31 LOG(ERROR) << "Root node with tag " << tag << " does not exist";
32 return false;
33 }
34 *has_children = node.GetFirstChildId() != sync_api::kInvalidId;
35 return true;
36 }
37
38 namespace {
39
40 // Fills in |extension_data_map| with data from
41 // extension_service.GetSyncDataList().
42 void SlurpClientData(
43 IsValidAndSyncablePredicate is_valid_and_syncable,
44 const ExtensionServiceInterface& extension_service,
45 ExtensionDataMap* extension_data_map) {
46 std::vector<ExtensionSyncData> sync_data_list =
47 extension_service.GetSyncDataList(is_valid_and_syncable);
48 for (std::vector<ExtensionSyncData>::const_iterator it =
49 sync_data_list.begin();
50 it != sync_data_list.end(); ++it) {
51 std::pair<ExtensionDataMap::iterator, bool> result =
52 extension_data_map->insert(std::make_pair(it->id, *it));
53 if (!result.second) {
54 // The value wasn't inserted, so merge it in.
55 result.first->second.Merge(*it);
56 }
57 }
58 }
59
60 // Gets the boilerplate error message for not being able to find a
61 // root node.
62 //
63 // TODO(akalin): Put this somewhere where all data types can use it.
64 std::string GetRootNodeDoesNotExistError(const char* root_node_tag) {
65 return
66 std::string("Server did not create the top-level ") +
67 root_node_tag +
68 " node. We might be running against an out-of-date server.";
69 }
70
71 // Gets the data from the server for extensions to be synced and
72 // updates |extension_data_map|.
73 bool SlurpServerData(
74 const char* root_node_tag,
75 const ExtensionSpecificsGetter extension_specifics_getter,
76 sync_api::UserShare* user_share,
77 ExtensionDataMap* extension_data_map) {
78 sync_api::WriteTransaction trans(FROM_HERE, user_share);
79 sync_api::ReadNode root(&trans);
80 if (!root.InitByTagLookup(root_node_tag)) {
81 LOG(ERROR) << GetRootNodeDoesNotExistError(root_node_tag);
82 return false;
83 }
84
85 int64 id = root.GetFirstChildId();
86 while (id != sync_api::kInvalidId) {
87 sync_api::ReadNode sync_node(&trans);
88 if (!sync_node.InitByIdLookup(id)) {
89 LOG(ERROR) << "Failed to fetch sync node for id " << id;
90 return false;
91 }
92 const sync_pb::ExtensionSpecifics& server_data =
93 (*extension_specifics_getter)(sync_node);
94 ExtensionSyncData sync_data;
95 if (!SpecificsToSyncData(server_data, &sync_data)) {
96 LOG(ERROR) << "Invalid extensions specifics for id " << id;
97 return false;
98 }
99 (*extension_data_map)[sync_data.id] = sync_data;
100 id = sync_node.GetSuccessorId();
101 }
102 return true;
103 }
104
105 } // namespace
106
107 bool SlurpExtensionData(const ExtensionSyncTraits& traits,
108 const ExtensionServiceInterface& extension_service,
109 sync_api::UserShare* user_share,
110 ExtensionDataMap* extension_data_map) {
111 // Read server-side data first so client user settings take
112 // precedence.
113 if (!SlurpServerData(
114 traits.root_node_tag, traits.extension_specifics_getter,
115 user_share, extension_data_map)) {
116 return false;
117 }
118
119 SlurpClientData(
120 traits.is_valid_and_syncable, extension_service,
121 extension_data_map);
122 return true;
123 }
124
125 namespace {
126
127 // Updates the server data from the given extension data. Returns
128 // whether or not the update was successful.
129 bool UpdateServer(
130 const ExtensionSyncTraits& traits,
131 const ExtensionSyncData& data,
132 sync_api::WriteTransaction* trans) {
133 sync_pb::ExtensionSpecifics specifics;
134 SyncDataToSpecifics(data, &specifics);
135 const std::string& id = data.id;
136 sync_api::WriteNode write_node(trans);
137 if (write_node.InitByClientTagLookup(traits.model_type, id)) {
138 (*traits.extension_specifics_setter)(specifics, &write_node);
139 } else {
140 sync_api::ReadNode root(trans);
141 if (!root.InitByTagLookup(traits.root_node_tag)) {
142 LOG(ERROR) << GetRootNodeDoesNotExistError(traits.root_node_tag);
143 return false;
144 }
145 sync_api::WriteNode create_node(trans);
146 if (!create_node.InitUniqueByCreation(traits.model_type, root, id)) {
147 LOG(ERROR) << "Could not create node for extension " << id;
148 return false;
149 }
150 (*traits.extension_specifics_setter)(specifics, &create_node);
151 }
152 return true;
153 }
154
155 } // namespace
156
157 bool FlushExtensionData(const ExtensionSyncTraits& traits,
158 const ExtensionDataMap& extension_data_map,
159 ExtensionServiceInterface* extension_service,
160 sync_api::UserShare* user_share) {
161 sync_api::WriteTransaction trans(FROM_HERE, user_share);
162 sync_api::ReadNode root(&trans);
163 if (!root.InitByTagLookup(traits.root_node_tag)) {
164 LOG(ERROR) << GetRootNodeDoesNotExistError(traits.root_node_tag);
165 return false;
166 }
167
168 // Update server and client as necessary.
169 for (ExtensionDataMap::const_iterator it = extension_data_map.begin();
170 it != extension_data_map.end(); ++it) {
171 const ExtensionSyncData& extension_data = it->second;
172 if (!UpdateServer(traits, extension_data, &trans)) {
173 LOG(ERROR) << "Could not update server data for extension "
174 << it->first;
175 return false;
176 }
177 extension_service->ProcessSyncData(extension_data,
178 traits.is_valid_and_syncable);
179 }
180 return true;
181 }
182
183 bool UpdateServerData(const ExtensionSyncTraits& traits,
184 const Extension& extension,
185 const ExtensionServiceInterface& extension_service,
186 sync_api::UserShare* user_share,
187 std::string* error) {
188 const std::string& id = extension.id();
189 ExtensionSyncData data;
190 if (!extension_service.GetSyncData(
191 extension, traits.is_valid_and_syncable, &data)) {
192 *error =
193 std::string("UpdateServerData() called for invalid or "
194 "unsyncable extension ") + id;
195 LOG(DFATAL) << *error;
196 return false;
197 }
198
199 sync_api::WriteTransaction trans(FROM_HERE, user_share);
200 if (!UpdateServer(traits, data, &trans)) {
201 *error =
202 std::string("Could not update server data for extension ") + id;
203 LOG(ERROR) << *error;
204 return false;
205 }
206 return true;
207 }
208
209 void RemoveServerData(const ExtensionSyncTraits& traits,
210 const std::string& id,
211 sync_api::UserShare* user_share) {
212 sync_api::WriteTransaction trans(FROM_HERE, user_share);
213 sync_api::WriteNode write_node(&trans);
214 if (write_node.InitByClientTagLookup(traits.model_type, id)) {
215 write_node.Remove();
216 } else {
217 LOG(ERROR) << "Server data does not exist for extension " << id;
218 }
219 }
220
221 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/extension_sync.h ('k') | chrome/browser/sync/glue/extension_sync_traits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698