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

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

Issue 3063002: Merge 53127 - Added checks to handle unsyncable extensions.... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/472/src/
Patch Set: Created 10 years, 5 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
« no previous file with comments | « chrome/browser/sync/glue/extension_model_associator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/sync/glue/extension_model_associator.h" 5 #include "chrome/browser/sync/glue/extension_model_associator.h"
6 6
7 #include <map> 7 #include <map>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 DCHECK(!extension_data->NeedsUpdate(source)); 48 DCHECK(!extension_data->NeedsUpdate(source));
49 } else { 49 } else {
50 extension_data->SetData(source, merge_user_properties, data); 50 extension_data->SetData(source, merge_user_properties, data);
51 } 51 }
52 return extension_data; 52 return extension_data;
53 } 53 }
54 54
55 void GetSyncableExtensionsClientData( 55 void GetSyncableExtensionsClientData(
56 const ExtensionList& extensions, 56 const ExtensionList& extensions,
57 ExtensionsService* extensions_service, 57 ExtensionsService* extensions_service,
58 std::set<std::string>* unsyncable_extensions,
58 ExtensionDataMap* extension_data_map) { 59 ExtensionDataMap* extension_data_map) {
59 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 60 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
60 for (ExtensionList::const_iterator it = extensions.begin(); 61 for (ExtensionList::const_iterator it = extensions.begin();
61 it != extensions.end(); ++it) { 62 it != extensions.end(); ++it) {
62 CHECK(*it); 63 CHECK(*it);
63 const Extension& extension = **it; 64 const Extension& extension = **it;
64 if (IsExtensionSyncable(extension)) { 65 if (IsExtensionSyncable(extension)) {
65 sync_pb::ExtensionSpecifics client_specifics; 66 sync_pb::ExtensionSpecifics client_specifics;
66 GetExtensionSpecifics(extension, extensions_service, 67 GetExtensionSpecifics(extension, extensions_service,
67 &client_specifics); 68 &client_specifics);
68 DcheckIsExtensionSpecificsValid(client_specifics); 69 DcheckIsExtensionSpecificsValid(client_specifics);
69 const ExtensionData& extension_data = 70 const ExtensionData& extension_data =
70 *SetOrCreateData(extension_data_map, 71 *SetOrCreateData(extension_data_map,
71 ExtensionData::CLIENT, true, client_specifics); 72 ExtensionData::CLIENT, true, client_specifics);
72 DcheckIsExtensionSpecificsValid(extension_data.merged_data()); 73 DcheckIsExtensionSpecificsValid(extension_data.merged_data());
73 // Assumes this is called before any server data is read. 74 // Assumes this is called before any server data is read.
74 DCHECK(extension_data.NeedsUpdate(ExtensionData::SERVER)); 75 DCHECK(extension_data.NeedsUpdate(ExtensionData::SERVER));
75 DCHECK(!extension_data.NeedsUpdate(ExtensionData::CLIENT)); 76 DCHECK(!extension_data.NeedsUpdate(ExtensionData::CLIENT));
77 } else {
78 unsyncable_extensions->insert(extension.id());
76 } 79 }
77 } 80 }
78 } 81 }
79 82
80 } // namespace 83 } // namespace
81 84
82 ExtensionModelAssociator::ExtensionModelAssociator( 85 ExtensionModelAssociator::ExtensionModelAssociator(
83 ProfileSyncService* sync_service) : sync_service_(sync_service) { 86 ProfileSyncService* sync_service) : sync_service_(sync_service) {
84 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 87 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
85 DCHECK(sync_service_); 88 DCHECK(sync_service_);
86 } 89 }
87 90
88 ExtensionModelAssociator::~ExtensionModelAssociator() { 91 ExtensionModelAssociator::~ExtensionModelAssociator() {
89 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 92 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
90 } 93 }
91 94
92 bool ExtensionModelAssociator::AssociateModels() { 95 bool ExtensionModelAssociator::AssociateModels() {
93 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 96 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
94 sync_api::WriteTransaction trans( 97 sync_api::WriteTransaction trans(
95 sync_service_->backend()->GetUserShareHandle()); 98 sync_service_->backend()->GetUserShareHandle());
96 sync_api::ReadNode root(&trans); 99 sync_api::ReadNode root(&trans);
97 if (!root.InitByTagLookup(kExtensionsTag)) { 100 if (!root.InitByTagLookup(kExtensionsTag)) {
98 LOG(ERROR) << kNoExtensionsFolderError; 101 LOG(ERROR) << kNoExtensionsFolderError;
99 return false; 102 return false;
100 } 103 }
101 104
105 std::set<std::string> unsyncable_extensions;
102 ExtensionDataMap extension_data_map; 106 ExtensionDataMap extension_data_map;
103 107
104 // Read client-side data. Do this first so server data takes 108 // Read client-side data. Do this first so server data takes
105 // precedence. 109 // precedence.
106 { 110 {
107 ExtensionsService* extensions_service = GetExtensionsService(); 111 ExtensionsService* extensions_service = GetExtensionsService();
108 112
109 const ExtensionList* extensions = extensions_service->extensions(); 113 const ExtensionList* extensions = extensions_service->extensions();
110 CHECK(extensions); 114 CHECK(extensions);
111 GetSyncableExtensionsClientData( 115 GetSyncableExtensionsClientData(
112 *extensions, extensions_service, &extension_data_map); 116 *extensions, extensions_service,
117 &unsyncable_extensions, &extension_data_map);
113 118
114 const ExtensionList* disabled_extensions = 119 const ExtensionList* disabled_extensions =
115 extensions_service->disabled_extensions(); 120 extensions_service->disabled_extensions();
116 CHECK(disabled_extensions); 121 CHECK(disabled_extensions);
117 GetSyncableExtensionsClientData( 122 GetSyncableExtensionsClientData(
118 *disabled_extensions, extensions_service, &extension_data_map); 123 *disabled_extensions, extensions_service,
124 &unsyncable_extensions, &extension_data_map);
119 } 125 }
120 126
121 // Read server-side data. 127 // Read server-side data.
122 { 128 {
123 int64 id = root.GetFirstChildId(); 129 int64 id = root.GetFirstChildId();
124 while (id != sync_api::kInvalidId) { 130 while (id != sync_api::kInvalidId) {
125 sync_api::ReadNode sync_node(&trans); 131 sync_api::ReadNode sync_node(&trans);
126 if (!sync_node.InitByIdLookup(id)) { 132 if (!sync_node.InitByIdLookup(id)) {
127 LOG(ERROR) << "Failed to fetch sync node for id " << id; 133 LOG(ERROR) << "Failed to fetch sync node for id " << id;
128 return false; 134 return false;
129 } 135 }
130 const sync_pb::ExtensionSpecifics& server_data = 136 const sync_pb::ExtensionSpecifics& server_data =
131 sync_node.GetExtensionSpecifics(); 137 sync_node.GetExtensionSpecifics();
132 if (!IsExtensionSpecificsValid(server_data)) { 138 if (!IsExtensionSpecificsValid(server_data)) {
133 LOG(ERROR) << "Invalid extensions specifics for id " << id; 139 LOG(ERROR) << "Invalid extensions specifics for id " << id;
134 return false; 140 return false;
135 } 141 }
136 // Pass in false for merge_user_properties so client user 142 // Don't process server data for extensions we know are
137 // settings always take precedence. 143 // unsyncable. This doesn't catch everything, as if we don't
138 const ExtensionData& extension_data = 144 // have the extension already installed we can't check, but we
139 *SetOrCreateData(&extension_data_map, 145 // also check at extension install time.
140 ExtensionData::SERVER, false, server_data); 146 if (unsyncable_extensions.find(server_data.id()) ==
141 DcheckIsExtensionSpecificsValid(extension_data.merged_data()); 147 unsyncable_extensions.end()) {
148 // Pass in false for merge_user_properties so client user
149 // settings always take precedence.
150 const ExtensionData& extension_data =
151 *SetOrCreateData(&extension_data_map,
152 ExtensionData::SERVER, false, server_data);
153 DcheckIsExtensionSpecificsValid(extension_data.merged_data());
154 }
142 id = sync_node.GetSuccessorId(); 155 id = sync_node.GetSuccessorId();
143 } 156 }
144 } 157 }
145 158
146 // Update server and client as necessary. 159 // Update server and client as necessary.
147 bool should_nudge_extension_updater = false; 160 bool should_nudge_extension_updater = false;
148 for (ExtensionDataMap::iterator it = extension_data_map.begin(); 161 for (ExtensionDataMap::iterator it = extension_data_map.begin();
149 it != extension_data_map.end(); ++it) { 162 it != extension_data_map.end(); ++it) {
150 ExtensionData* extension_data = &it->second; 163 ExtensionData* extension_data = &it->second;
151 // Update server first. 164 // Update server first.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 210 }
198 211
199 bool ExtensionModelAssociator::OnClientUpdate(const std::string& id) { 212 bool ExtensionModelAssociator::OnClientUpdate(const std::string& id) {
200 sync_api::WriteTransaction trans( 213 sync_api::WriteTransaction trans(
201 sync_service_->backend()->GetUserShareHandle()); 214 sync_service_->backend()->GetUserShareHandle());
202 sync_api::ReadNode root(&trans); 215 sync_api::ReadNode root(&trans);
203 if (!root.InitByTagLookup(kExtensionsTag)) { 216 if (!root.InitByTagLookup(kExtensionsTag)) {
204 LOG(ERROR) << kNoExtensionsFolderError; 217 LOG(ERROR) << kNoExtensionsFolderError;
205 return false; 218 return false;
206 } 219 }
207 220 ExtensionsService* extensions_service = GetExtensionsService();
208 sync_pb::ExtensionSpecifics client_data; 221 Extension* extension = extensions_service->GetExtensionById(id, true);
209 if (GetExtensionDataFromClient(id, &client_data)) { 222 if (extension) {
223 if (!IsExtensionSyncable(*extension)) {
224 LOG(DFATAL) << "OnClientUpdate() called for non-syncable extension "
225 << id;
226 return false;
227 }
228 sync_pb::ExtensionSpecifics client_data;
229 GetExtensionSpecifics(*extension, extensions_service, &client_data);
230 DcheckIsExtensionSpecificsValid(client_data);
210 ExtensionData extension_data = 231 ExtensionData extension_data =
211 ExtensionData::FromData(ExtensionData::CLIENT, client_data); 232 ExtensionData::FromData(ExtensionData::CLIENT, client_data);
212 sync_pb::ExtensionSpecifics server_data; 233 sync_pb::ExtensionSpecifics server_data;
213 if (GetExtensionDataFromServer(id, &trans, root, &server_data)) { 234 if (GetExtensionDataFromServer(id, &trans, root, &server_data)) {
214 extension_data = 235 extension_data =
215 ExtensionData::FromData(ExtensionData::SERVER, server_data); 236 ExtensionData::FromData(ExtensionData::SERVER, server_data);
216 extension_data.SetData(ExtensionData::CLIENT, true, client_data); 237 extension_data.SetData(ExtensionData::CLIENT, true, client_data);
217 } 238 }
218 if (extension_data.NeedsUpdate(ExtensionData::SERVER)) { 239 if (extension_data.NeedsUpdate(ExtensionData::SERVER)) {
219 if (!UpdateServer(&extension_data, &trans, root)) { 240 if (!UpdateServer(&extension_data, &trans, root)) {
(...skipping 18 matching lines...) Expand all
238 } 259 }
239 } 260 }
240 return true; 261 return true;
241 } 262 }
242 263
243 void ExtensionModelAssociator::OnServerUpdate( 264 void ExtensionModelAssociator::OnServerUpdate(
244 const sync_pb::ExtensionSpecifics& server_data) { 265 const sync_pb::ExtensionSpecifics& server_data) {
245 DcheckIsExtensionSpecificsValid(server_data); 266 DcheckIsExtensionSpecificsValid(server_data);
246 ExtensionData extension_data = 267 ExtensionData extension_data =
247 ExtensionData::FromData(ExtensionData::SERVER, server_data); 268 ExtensionData::FromData(ExtensionData::SERVER, server_data);
248 sync_pb::ExtensionSpecifics client_data; 269 ExtensionsService* extensions_service = GetExtensionsService();
249 if (GetExtensionDataFromClient(server_data.id(), &client_data)) { 270 Extension* extension =
250 ExtensionData extension_data = 271 extensions_service->GetExtensionById(server_data.id(), true);
272 if (extension) {
273 if (!IsExtensionSyncable(*extension)) {
274 // Ignore updates for non-syncable extensions (we may get those
275 // for extensions that were previously syncable).
276 return;
277 }
278 sync_pb::ExtensionSpecifics client_data;
279 GetExtensionSpecifics(*extension, extensions_service, &client_data);
280 DcheckIsExtensionSpecificsValid(client_data);
281 extension_data =
251 ExtensionData::FromData(ExtensionData::CLIENT, client_data); 282 ExtensionData::FromData(ExtensionData::CLIENT, client_data);
252 extension_data.SetData(ExtensionData::SERVER, true, server_data); 283 extension_data.SetData(ExtensionData::SERVER, true, server_data);
253 } 284 }
254 DCHECK(!extension_data.NeedsUpdate(ExtensionData::SERVER)); 285 DCHECK(!extension_data.NeedsUpdate(ExtensionData::SERVER));
255 if (extension_data.NeedsUpdate(ExtensionData::CLIENT)) { 286 if (extension_data.NeedsUpdate(ExtensionData::CLIENT)) {
256 TryUpdateClient(&extension_data); 287 TryUpdateClient(&extension_data);
257 if (extension_data.NeedsUpdate(ExtensionData::CLIENT)) { 288 if (extension_data.NeedsUpdate(ExtensionData::CLIENT)) {
258 NudgeExtensionUpdater(); 289 NudgeExtensionUpdater();
259 } 290 }
260 } 291 }
261 DCHECK(!extension_data.NeedsUpdate(ExtensionData::SERVER)); 292 DCHECK(!extension_data.NeedsUpdate(ExtensionData::SERVER));
262 } 293 }
263 294
264 void ExtensionModelAssociator::OnServerRemove(const std::string& id) { 295 void ExtensionModelAssociator::OnServerRemove(const std::string& id) {
265 ExtensionsService* extensions_service = GetExtensionsService(); 296 ExtensionsService* extensions_service = GetExtensionsService();
266 Extension* extension = extensions_service->GetExtensionById(id, true); 297 Extension* extension = extensions_service->GetExtensionById(id, true);
267 if (extension) { 298 if (extension) {
268 extensions_service->UninstallExtension(id, false); 299 if (IsExtensionSyncable(*extension)) {
300 extensions_service->UninstallExtension(id, false);
301 }
269 } else { 302 } else {
270 LOG(ERROR) << "Trying to uninstall nonexistent extension " << id; 303 LOG(ERROR) << "Trying to uninstall nonexistent extension " << id;
271 } 304 }
272 } 305 }
273 306
274 ExtensionsService* ExtensionModelAssociator::GetExtensionsService() { 307 ExtensionsService* ExtensionModelAssociator::GetExtensionsService() {
275 CHECK(sync_service_); 308 CHECK(sync_service_);
276 Profile* profile = sync_service_->profile(); 309 Profile* profile = sync_service_->profile();
277 CHECK(profile); 310 CHECK(profile);
278 ExtensionsService* extensions_service = profile->GetExtensionsService(); 311 ExtensionsService* extensions_service = profile->GetExtensionsService();
279 CHECK(extensions_service); 312 CHECK(extensions_service);
280 return extensions_service; 313 return extensions_service;
281 } 314 }
282 315
283 bool ExtensionModelAssociator::GetExtensionDataFromClient(
284 const std::string& id, sync_pb::ExtensionSpecifics* client_data) {
285 ExtensionsService* extensions_service = GetExtensionsService();
286 Extension* extension = extensions_service->GetExtensionById(id, true);
287 if (!extension) {
288 return false;
289 }
290 GetExtensionSpecifics(*extension, extensions_service, client_data);
291 DcheckIsExtensionSpecificsValid(*client_data);
292 return true;
293 }
294
295 bool ExtensionModelAssociator::GetExtensionDataFromServer( 316 bool ExtensionModelAssociator::GetExtensionDataFromServer(
296 const std::string& id, sync_api::WriteTransaction* trans, 317 const std::string& id, sync_api::WriteTransaction* trans,
297 const sync_api::ReadNode& root, 318 const sync_api::ReadNode& root,
298 sync_pb::ExtensionSpecifics* server_data) { 319 sync_pb::ExtensionSpecifics* server_data) {
299 sync_api::ReadNode sync_node(trans); 320 sync_api::ReadNode sync_node(trans);
300 if (!sync_node.InitByClientTagLookup(syncable::EXTENSIONS, id)) { 321 if (!sync_node.InitByClientTagLookup(syncable::EXTENSIONS, id)) {
301 LOG(ERROR) << "Failed to fetch sync node for id " << id; 322 LOG(ERROR) << "Failed to fetch sync node for id " << id;
302 return false; 323 return false;
303 } 324 }
304 const sync_pb::ExtensionSpecifics& read_server_data = 325 const sync_pb::ExtensionSpecifics& read_server_data =
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 ExtensionData* extension_data) { 374 ExtensionData* extension_data) {
354 DCHECK(!extension_data->NeedsUpdate(ExtensionData::SERVER)); 375 DCHECK(!extension_data->NeedsUpdate(ExtensionData::SERVER));
355 DCHECK(extension_data->NeedsUpdate(ExtensionData::CLIENT)); 376 DCHECK(extension_data->NeedsUpdate(ExtensionData::CLIENT));
356 const sync_pb::ExtensionSpecifics& specifics = 377 const sync_pb::ExtensionSpecifics& specifics =
357 extension_data->merged_data(); 378 extension_data->merged_data();
358 DcheckIsExtensionSpecificsValid(specifics); 379 DcheckIsExtensionSpecificsValid(specifics);
359 ExtensionsService* extensions_service = GetExtensionsService(); 380 ExtensionsService* extensions_service = GetExtensionsService();
360 const std::string& id = specifics.id(); 381 const std::string& id = specifics.id();
361 Extension* extension = extensions_service->GetExtensionById(id, true); 382 Extension* extension = extensions_service->GetExtensionById(id, true);
362 if (extension) { 383 if (extension) {
384 if (!IsExtensionSyncable(*extension)) {
385 LOG(DFATAL) << "TryUpdateClient() called for non-syncable extension "
386 << extension->id();
387 return;
388 }
363 SetExtensionProperties(specifics, extensions_service, extension); 389 SetExtensionProperties(specifics, extensions_service, extension);
364 { 390 {
365 sync_pb::ExtensionSpecifics extension_specifics; 391 sync_pb::ExtensionSpecifics extension_specifics;
366 GetExtensionSpecifics(*extension, extensions_service, 392 GetExtensionSpecifics(*extension, extensions_service,
367 &extension_specifics); 393 &extension_specifics);
368 DCHECK(AreExtensionSpecificsUserPropertiesEqual( 394 DCHECK(AreExtensionSpecificsUserPropertiesEqual(
369 specifics, extension_specifics)) 395 specifics, extension_specifics))
370 << ExtensionSpecificsToString(specifics) << ", " 396 << ExtensionSpecificsToString(specifics) << ", "
371 << ExtensionSpecificsToString(extension_specifics); 397 << ExtensionSpecificsToString(extension_specifics);
372 } 398 }
(...skipping 18 matching lines...) Expand all
391 // ExtensionsService in ProfileImpl::InitExtensions()). 417 // ExtensionsService in ProfileImpl::InitExtensions()).
392 if (extension_updater) { 418 if (extension_updater) {
393 extension_updater->CheckNow(); 419 extension_updater->CheckNow();
394 } else { 420 } else {
395 LOG(DFATAL) << "Extension updater unexpectedly NULL; " 421 LOG(DFATAL) << "Extension updater unexpectedly NULL; "
396 << "auto-updates may be turned off"; 422 << "auto-updates may be turned off";
397 } 423 }
398 } 424 }
399 425
400 } // namespace browser_sync 426 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/extension_model_associator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698