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

Side by Side Diff: chrome/browser/extensions/extension_sync_service.cc

Issue 1240573012: Extension syncing: Introduce a NeedsSync pref (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ext_sync_uninstall
Patch Set: (b); hackfix sync_integration_tests Created 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/extension_sync_service.h" 5 #include "chrome/browser/extensions/extension_sync_service.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "base/threading/thread_restrictions.h" 9 #include "base/threading/thread_restrictions.h"
10 #include "chrome/browser/extensions/bookmark_app_helper.h" 10 #include "chrome/browser/extensions/bookmark_app_helper.h"
(...skipping 17 matching lines...) Expand all
28 #include "extensions/common/extension_set.h" 28 #include "extensions/common/extension_set.h"
29 #include "extensions/common/image_util.h" 29 #include "extensions/common/image_util.h"
30 #include "sync/api/sync_change.h" 30 #include "sync/api/sync_change.h"
31 #include "sync/api/sync_error_factory.h" 31 #include "sync/api/sync_error_factory.h"
32 32
33 using extensions::Extension; 33 using extensions::Extension;
34 using extensions::ExtensionPrefs; 34 using extensions::ExtensionPrefs;
35 using extensions::ExtensionRegistry; 35 using extensions::ExtensionRegistry;
36 using extensions::ExtensionSet; 36 using extensions::ExtensionSet;
37 using extensions::ExtensionSyncData; 37 using extensions::ExtensionSyncData;
38 using extensions::PendingEnables;
39 using extensions::SyncBundle; 38 using extensions::SyncBundle;
40 39
41 namespace { 40 namespace {
42 41
43 void OnWebApplicationInfoLoaded( 42 void OnWebApplicationInfoLoaded(
44 WebApplicationInfo synced_info, 43 WebApplicationInfo synced_info,
45 base::WeakPtr<ExtensionService> extension_service, 44 base::WeakPtr<ExtensionService> extension_service,
46 const WebApplicationInfo& loaded_info) { 45 const WebApplicationInfo& loaded_info) {
47 DCHECK_EQ(synced_info.app_url, loaded_info.app_url); 46 DCHECK_EQ(synced_info.app_url, loaded_info.app_url);
48 47
(...skipping 23 matching lines...) Expand all
72 // Otherwise, unset. 71 // Otherwise, unset.
73 return ExtensionSyncData::BOOLEAN_UNSET; 72 return ExtensionSyncData::BOOLEAN_UNSET;
74 } 73 }
75 74
76 // Returns true if the sync type of |extension| matches |type|. 75 // Returns true if the sync type of |extension| matches |type|.
77 bool IsCorrectSyncType(const Extension& extension, syncer::ModelType type) { 76 bool IsCorrectSyncType(const Extension& extension, syncer::ModelType type) {
78 return (type == syncer::EXTENSIONS && extension.is_extension()) || 77 return (type == syncer::EXTENSIONS && extension.is_extension()) ||
79 (type == syncer::APPS && extension.is_app()); 78 (type == syncer::APPS && extension.is_app());
80 } 79 }
81 80
81 syncer::SyncDataList ToSyncerSyncDataList(
82 const std::vector<ExtensionSyncData>& data) {
83 syncer::SyncDataList result;
84 result.reserve(data.size());
85 for (const ExtensionSyncData& item : data)
86 result.push_back(item.GetSyncData());
87 return result;
88 }
89
82 } // namespace 90 } // namespace
83 91
84 ExtensionSyncService::ExtensionSyncService(Profile* profile, 92 ExtensionSyncService::ExtensionSyncService(Profile* profile,
85 ExtensionPrefs* extension_prefs, 93 ExtensionPrefs* extension_prefs,
86 ExtensionService* extension_service) 94 ExtensionService* extension_service)
87 : profile_(profile), 95 : profile_(profile),
88 extension_prefs_(extension_prefs), 96 extension_prefs_(extension_prefs),
89 extension_service_(extension_service), 97 extension_service_(extension_service) {
90 app_sync_bundle_(this),
91 extension_sync_bundle_(this),
92 pending_app_enables_(make_scoped_ptr(new sync_driver::SyncPrefs(
93 extension_prefs_->pref_service())),
94 &app_sync_bundle_,
95 syncer::APPS),
96 pending_extension_enables_(make_scoped_ptr(new sync_driver::SyncPrefs(
97 extension_prefs_->pref_service())),
98 &extension_sync_bundle_,
99 syncer::EXTENSIONS) {
100 SetSyncStartFlare(sync_start_util::GetFlareForSyncableService( 98 SetSyncStartFlare(sync_start_util::GetFlareForSyncableService(
101 profile_->GetPath())); 99 profile_->GetPath()));
102 100
103 extension_service_->set_extension_sync_service(this);
104 extension_prefs_->app_sorting()->SetExtensionSyncService(this); 101 extension_prefs_->app_sorting()->SetExtensionSyncService(this);
105 } 102 }
106 103
107 ExtensionSyncService::~ExtensionSyncService() {} 104 ExtensionSyncService::~ExtensionSyncService() {}
108 105
109 // static 106 // static
110 ExtensionSyncService* ExtensionSyncService::Get( 107 ExtensionSyncService* ExtensionSyncService::Get(
111 content::BrowserContext* context) { 108 content::BrowserContext* context) {
112 return ExtensionSyncServiceFactory::GetForBrowserContext(context); 109 return ExtensionSyncServiceFactory::GetForBrowserContext(context);
113 } 110 }
114 111
115 void ExtensionSyncService::SyncUninstallExtension( 112 void ExtensionSyncService::SyncUninstallExtension(
116 const extensions::Extension& extension) { 113 const extensions::Extension& extension) {
117 if (!extensions::util::ShouldSync(&extension, profile_)) 114 if (!extensions::util::ShouldSync(&extension, profile_))
118 return; 115 return;
119 116
120 // TODO(tim): If we get here and IsSyncing is false, this will cause 117 // TODO(tim): If we get here and IsSyncing is false, this will cause
121 // "back from the dead" style bugs, because sync will add-back the extension 118 // "back from the dead" style bugs, because sync will add-back the extension
122 // that was uninstalled here when MergeDataAndStartSyncing is called. 119 // that was uninstalled here when MergeDataAndStartSyncing is called.
123 // See crbug.com/256795. 120 // See crbug.com/256795.
124 syncer::ModelType type = 121 syncer::ModelType type =
125 extension.is_app() ? syncer::APPS : syncer::EXTENSIONS; 122 extension.is_app() ? syncer::APPS : syncer::EXTENSIONS;
126 SyncBundle* bundle = GetSyncBundle(type); 123 SyncBundle* bundle = GetSyncBundle(type);
127 if (!bundle->IsSyncing()) { 124 if (bundle->IsSyncing()) {
128 if (extension_service_->is_ready() && !flare_.is_null()) 125 bundle->PushSyncDeletion(extension.id(),
129 flare_.Run(type); // Tell sync to start ASAP. 126 CreateSyncData(extension).GetSyncData());
130 return; 127 } else if (extension_service_->is_ready() && !flare_.is_null()) {
128 flare_.Run(type); // Tell sync to start ASAP.
131 } 129 }
132 const std::string& id = extension.id();
133 if (bundle->HasExtensionId(id))
134 bundle->PushSyncDeletion(id, CreateSyncData(extension).GetSyncData());
135 }
136
137 void ExtensionSyncService::SyncEnableExtension(const Extension& extension) {
138 // Syncing may not have started yet, so handle pending enables.
139 if (extensions::util::ShouldSync(&extension, profile_))
140 GetPendingEnables(extension.is_app())->Add(extension.id());
141
142 SyncExtensionChangeIfNeeded(extension);
143 }
144
145 void ExtensionSyncService::SyncDisableExtension(const Extension& extension) {
146 // Syncing may not have started yet, so handle pending enables.
147 if (extensions::util::ShouldSync(&extension, profile_))
148 GetPendingEnables(extension.is_app())->Remove(extension.id());
149
150 SyncExtensionChangeIfNeeded(extension);
151 } 130 }
152 131
153 void ExtensionSyncService::SyncExtensionChangeIfNeeded( 132 void ExtensionSyncService::SyncExtensionChangeIfNeeded(
154 const Extension& extension) { 133 const Extension& extension) {
155 if (!extensions::util::ShouldSync(&extension, profile_)) 134 if (!extensions::util::ShouldSync(&extension, profile_))
156 return; 135 return;
157 136
158 syncer::ModelType type = 137 syncer::ModelType type =
159 extension.is_app() ? syncer::APPS : syncer::EXTENSIONS; 138 extension.is_app() ? syncer::APPS : syncer::EXTENSIONS;
160 SyncBundle* bundle = GetSyncBundle(type); 139 SyncBundle* bundle = GetSyncBundle(type);
161 if (bundle->IsSyncing()) 140 if (bundle->IsSyncing()) {
162 bundle->PushSyncAddOrUpdate(extension); 141 bundle->PushSyncAddOrUpdate(extension.id(),
163 else if (extension_service_->is_ready() && !flare_.is_null()) 142 CreateSyncData(extension).GetSyncData());
164 flare_.Run(type); 143 DCHECK(!ExtensionPrefs::Get(profile_)->NeedsSync(extension.id()));
144 } else {
145 ExtensionPrefs::Get(profile_)->SetNeedsSync(extension.id(), true);
146 if (extension_service_->is_ready() && !flare_.is_null())
147 flare_.Run(type); // Tell sync to start ASAP.
148 }
165 } 149 }
166 150
167 syncer::SyncMergeResult ExtensionSyncService::MergeDataAndStartSyncing( 151 syncer::SyncMergeResult ExtensionSyncService::MergeDataAndStartSyncing(
168 syncer::ModelType type, 152 syncer::ModelType type,
169 const syncer::SyncDataList& initial_sync_data, 153 const syncer::SyncDataList& initial_sync_data,
170 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 154 scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
171 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { 155 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
172 CHECK(sync_processor.get()); 156 CHECK(sync_processor.get());
173 LOG_IF(FATAL, type != syncer::EXTENSIONS && type != syncer::APPS) 157 LOG_IF(FATAL, type != syncer::EXTENSIONS && type != syncer::APPS)
174 << "Got " << type << " ModelType"; 158 << "Got " << type << " ModelType";
175 159
176 SyncBundle* bundle = GetSyncBundle(type); 160 SyncBundle* bundle = GetSyncBundle(type);
177 bool is_apps = (type == syncer::APPS); 161 bundle->StartSyncing(sync_processor.Pass());
178 162
179 bundle->MergeDataAndStartSyncing(initial_sync_data, sync_processor.Pass()); 163 // Apply the initial sync data, filtering out any items where we have more
180 GetPendingEnables(is_apps)->OnSyncStarted(extension_service_); 164 // recent local changes. Also tell the SyncBundle the extension IDs.
165 for (const syncer::SyncData& sync_data : initial_sync_data) {
166 scoped_ptr<ExtensionSyncData> extension_sync_data(
167 ExtensionSyncData::CreateFromSyncData(sync_data));
168 // If the extension has local state that needs to be synced, ignore this
169 // change (we assume the local state is more recent).
170 if (extension_sync_data &&
171 !ExtensionPrefs::Get(profile_)->NeedsSync(extension_sync_data->id())) {
172 ApplySyncData(*extension_sync_data);
173 }
174 }
181 175
182 // Process local extensions. 176 // Now push those local changes to sync.
183 // TODO(yoz): Determine whether pending extensions should be considered too. 177 // TODO(treib,kalman): We should only have to send out changes for extensions
184 // See crbug.com/104399. 178 // which have NeedsSync set (i.e. |GetLocalSyncDataList(type, false)|). That
185 bundle->PushSyncDataList(GetAllSyncData(type)); 179 // makes some sync_integration_tests fail though - figure out why and fix it!
180 std::vector<ExtensionSyncData> data_list = GetLocalSyncDataList(type, true);
Marc Treib 2015/07/21 10:54:00 I still haven't figured out the actual problem her
not at google - send to devlin 2015/07/21 13:43:30 I'll leave it to your judgement. If you think it's
181 bundle->PushSyncDataList(ToSyncerSyncDataList(data_list));
182 for (const ExtensionSyncData& data : data_list)
183 ExtensionPrefs::Get(profile_)->SetNeedsSync(data.id(), false);
186 184
187 if (is_apps) 185 if (type == syncer::APPS)
188 extension_prefs_->app_sorting()->FixNTPOrdinalCollisions(); 186 extension_prefs_->app_sorting()->FixNTPOrdinalCollisions();
189 187
190 return syncer::SyncMergeResult(type); 188 return syncer::SyncMergeResult(type);
191 } 189 }
192 190
193 void ExtensionSyncService::StopSyncing(syncer::ModelType type) { 191 void ExtensionSyncService::StopSyncing(syncer::ModelType type) {
194 GetSyncBundle(type)->Reset(); 192 GetSyncBundle(type)->Reset();
195 } 193 }
196 194
197 syncer::SyncDataList ExtensionSyncService::GetAllSyncData( 195 syncer::SyncDataList ExtensionSyncService::GetAllSyncData(
198 syncer::ModelType type) const { 196 syncer::ModelType type) const {
199 std::vector<ExtensionSyncData> data = GetSyncDataList(type); 197 const SyncBundle* bundle = GetSyncBundle(type);
200 syncer::SyncDataList result; 198 if (!bundle->IsSyncing())
201 result.reserve(data.size()); 199 return syncer::SyncDataList();
202 for (const ExtensionSyncData& item : data) 200
203 result.push_back(item.GetSyncData()); 201 std::vector<extensions::ExtensionSyncData> sync_data_list =
204 return result; 202 GetLocalSyncDataList(type, true);
203
204 // Add pending data (where the local extension is either not installed yet or
205 // outdated).
206 std::vector<ExtensionSyncData> pending_extensions = bundle->GetPendingData();
207 sync_data_list.insert(sync_data_list.begin(),
208 pending_extensions.begin(),
209 pending_extensions.end());
210
211 return ToSyncerSyncDataList(sync_data_list);
205 } 212 }
206 213
207 syncer::SyncError ExtensionSyncService::ProcessSyncChanges( 214 syncer::SyncError ExtensionSyncService::ProcessSyncChanges(
208 const tracked_objects::Location& from_here, 215 const tracked_objects::Location& from_here,
209 const syncer::SyncChangeList& change_list) { 216 const syncer::SyncChangeList& change_list) {
210 for (const syncer::SyncChange& sync_change : change_list) { 217 for (const syncer::SyncChange& sync_change : change_list) {
211 syncer::ModelType type = sync_change.sync_data().GetDataType(); 218 scoped_ptr<ExtensionSyncData> extension_sync_data(
212 GetSyncBundle(type)->ApplySyncChange(sync_change); 219 ExtensionSyncData::CreateFromSyncChange(sync_change));
220 if (extension_sync_data)
221 ApplySyncData(*extension_sync_data);
213 } 222 }
214 223
215 extension_prefs_->app_sorting()->FixNTPOrdinalCollisions(); 224 extension_prefs_->app_sorting()->FixNTPOrdinalCollisions();
216 225
217 return syncer::SyncError(); 226 return syncer::SyncError();
218 } 227 }
219 228
220 ExtensionSyncData ExtensionSyncService::CreateSyncData( 229 ExtensionSyncData ExtensionSyncService::CreateSyncData(
221 const extensions::Extension& extension) const { 230 const extensions::Extension& extension) const {
222 bool enabled = extension_service_->IsExtensionEnabled(extension.id()); 231 bool enabled = extension_service_->IsExtensionEnabled(extension.id());
(...skipping 13 matching lines...) Expand all
236 extension_prefs_->app_sorting()->GetPageOrdinal(extension.id()), 245 extension_prefs_->app_sorting()->GetPageOrdinal(extension.id()),
237 extensions::GetLaunchTypePrefValue(extension_prefs_, extension.id())); 246 extensions::GetLaunchTypePrefValue(extension_prefs_, extension.id()));
238 } 247 }
239 return ExtensionSyncData( 248 return ExtensionSyncData(
240 extension, enabled, disable_reasons, incognito_enabled, remote_install, 249 extension, enabled, disable_reasons, incognito_enabled, remote_install,
241 allowed_on_all_url); 250 allowed_on_all_url);
242 } 251 }
243 252
244 bool ExtensionSyncService::ApplySyncData( 253 bool ExtensionSyncService::ApplySyncData(
245 const ExtensionSyncData& extension_sync_data) { 254 const ExtensionSyncData& extension_sync_data) {
255 syncer::ModelType type = extension_sync_data.is_app() ? syncer::APPS
256 : syncer::EXTENSIONS;
257 SyncBundle* bundle = GetSyncBundle(type);
258 bundle->ApplySyncData(extension_sync_data);
259
246 const std::string& id = extension_sync_data.id(); 260 const std::string& id = extension_sync_data.id();
247 261
248 if (extension_sync_data.is_app()) { 262 if (extension_sync_data.is_app()) {
249 if (extension_sync_data.app_launch_ordinal().IsValid() && 263 if (extension_sync_data.app_launch_ordinal().IsValid() &&
250 extension_sync_data.page_ordinal().IsValid()) { 264 extension_sync_data.page_ordinal().IsValid()) {
251 extension_prefs_->app_sorting()->SetAppLaunchOrdinal( 265 extension_prefs_->app_sorting()->SetAppLaunchOrdinal(
252 id, 266 id,
253 extension_sync_data.app_launch_ordinal()); 267 extension_sync_data.app_launch_ordinal());
254 extension_prefs_->app_sorting()->SetPageOrdinal( 268 extension_prefs_->app_sorting()->SetPageOrdinal(
255 id, 269 id,
256 extension_sync_data.page_ordinal()); 270 extension_sync_data.page_ordinal());
257 } 271 }
258 272
259 // The corresponding validation of this value during AppSyncData population 273 // The corresponding validation of this value during ExtensionSyncData
260 // is in AppSyncData::PopulateAppSpecifics. 274 // population is in ExtensionSyncData::ToAppSpecifics.
261 if (extension_sync_data.launch_type() >= extensions::LAUNCH_TYPE_FIRST && 275 if (extension_sync_data.launch_type() >= extensions::LAUNCH_TYPE_FIRST &&
262 extension_sync_data.launch_type() < extensions::NUM_LAUNCH_TYPES) { 276 extension_sync_data.launch_type() < extensions::NUM_LAUNCH_TYPES) {
263 extensions::SetLaunchType( 277 extensions::SetLaunchType(
264 profile_, id, extension_sync_data.launch_type()); 278 profile_, id, extension_sync_data.launch_type());
265 } 279 }
266 280
267 if (!extension_sync_data.bookmark_app_url().empty()) 281 if (!extension_sync_data.bookmark_app_url().empty())
268 ApplyBookmarkAppSyncData(extension_sync_data); 282 ApplyBookmarkAppSyncData(extension_sync_data);
269 } 283 }
270 284
271 syncer::ModelType type = extension_sync_data.is_app() ? syncer::APPS
272 : syncer::EXTENSIONS;
273
274 if (!ApplyExtensionSyncDataHelper(extension_sync_data, type)) { 285 if (!ApplyExtensionSyncDataHelper(extension_sync_data, type)) {
275 GetSyncBundle(type)->AddPendingExtension(id, extension_sync_data); 286 bundle->AddPendingExtension(id, extension_sync_data);
276 extension_service_->CheckForUpdatesSoon(); 287 extension_service_->CheckForUpdatesSoon();
277 return false; 288 return false;
278 } 289 }
279 290
280 return true; 291 return true;
281 } 292 }
282 293
283 void ExtensionSyncService::ApplyBookmarkAppSyncData( 294 void ExtensionSyncService::ApplyBookmarkAppSyncData(
284 const extensions::ExtensionSyncData& extension_sync_data) { 295 const extensions::ExtensionSyncData& extension_sync_data) {
285 DCHECK(extension_sync_data.is_app()); 296 DCHECK(extension_sync_data.is_app());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 349
339 if (ext) 350 if (ext)
340 SyncExtensionChangeIfNeeded(*ext); 351 SyncExtensionChangeIfNeeded(*ext);
341 } 352 }
342 353
343 void ExtensionSyncService::SetSyncStartFlare( 354 void ExtensionSyncService::SetSyncStartFlare(
344 const syncer::SyncableService::StartSyncFlare& flare) { 355 const syncer::SyncableService::StartSyncFlare& flare) {
345 flare_ = flare; 356 flare_ = flare;
346 } 357 }
347 358
348 bool ExtensionSyncService::IsPendingEnable(
349 const std::string& extension_id) const {
350 return pending_app_enables_.Contains(extension_id) ||
351 pending_extension_enables_.Contains(extension_id);
352 }
353
354 SyncBundle* ExtensionSyncService::GetSyncBundle(syncer::ModelType type) { 359 SyncBundle* ExtensionSyncService::GetSyncBundle(syncer::ModelType type) {
355 return const_cast<SyncBundle*>( 360 return const_cast<SyncBundle*>(
356 const_cast<const ExtensionSyncService&>(*this).GetSyncBundle(type)); 361 const_cast<const ExtensionSyncService&>(*this).GetSyncBundle(type));
357 } 362 }
358 363
359 const SyncBundle* ExtensionSyncService::GetSyncBundle( 364 const SyncBundle* ExtensionSyncService::GetSyncBundle(
360 syncer::ModelType type) const { 365 syncer::ModelType type) const {
361 return (type == syncer::APPS) ? &app_sync_bundle_ : &extension_sync_bundle_; 366 return (type == syncer::APPS) ? &app_sync_bundle_ : &extension_sync_bundle_;
362 } 367 }
363 368
364 extensions::PendingEnables* ExtensionSyncService::GetPendingEnables( 369 std::vector<ExtensionSyncData> ExtensionSyncService::GetLocalSyncDataList(
365 bool is_apps) { 370 syncer::ModelType type,
366 return is_apps ? &pending_app_enables_ : &pending_extension_enables_; 371 bool include_everything) const {
367 } 372 // Collect the local state. FillSyncDataList will filter out extensions for
368 373 // which we have pending data that should be used instead.
369 std::vector<ExtensionSyncData> ExtensionSyncService::GetSyncDataList(
370 syncer::ModelType type) const {
371 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); 374 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
372 std::vector<ExtensionSyncData> extension_sync_list; 375 std::vector<ExtensionSyncData> data;
373 FillSyncDataList(registry->enabled_extensions(), type, &extension_sync_list); 376 // TODO(treib, kalman): Should we be including blacklisted/blocked extensions
374 FillSyncDataList(registry->disabled_extensions(), type, &extension_sync_list); 377 // here? I.e. just calling registry->GeneratedInstalledExtensionsSet()?
378 // It would be more consistent, but the danger is that the black/blocklist
379 // hasn't been updated on all clients by the time sync has kicked in -
380 // so it's safest not to. Take care to add any other extension lists here
381 // in the future if they are added.
375 FillSyncDataList( 382 FillSyncDataList(
376 registry->terminated_extensions(), type, &extension_sync_list); 383 registry->enabled_extensions(), type, include_everything, &data);
377 384 FillSyncDataList(
378 std::vector<ExtensionSyncData> pending_extensions = 385 registry->disabled_extensions(), type, include_everything, &data);
379 GetSyncBundle(type)->GetPendingData(); 386 FillSyncDataList(
380 extension_sync_list.insert(extension_sync_list.begin(), 387 registry->terminated_extensions(), type, include_everything, &data);
381 pending_extensions.begin(), 388 return data;
382 pending_extensions.end());
383
384 return extension_sync_list;
385 } 389 }
386 390
387 void ExtensionSyncService::FillSyncDataList( 391 void ExtensionSyncService::FillSyncDataList(
388 const ExtensionSet& extensions, 392 const ExtensionSet& extensions,
389 syncer::ModelType type, 393 syncer::ModelType type,
394 bool include_everything,
390 std::vector<ExtensionSyncData>* sync_data_list) const { 395 std::vector<ExtensionSyncData>* sync_data_list) const {
391 const SyncBundle* bundle = GetSyncBundle(type); 396 const SyncBundle* bundle = GetSyncBundle(type);
392 for (const scoped_refptr<const Extension>& extension : extensions) { 397 for (const scoped_refptr<const Extension>& extension : extensions) {
393 if (IsCorrectSyncType(*extension, type) && 398 if (IsCorrectSyncType(*extension, type) &&
394 extensions::util::ShouldSync(extension.get(), profile_) && 399 extensions::util::ShouldSync(extension.get(), profile_) &&
395 bundle->ShouldIncludeInLocalSyncDataList(*extension)) { 400 !bundle->HasPendingExtensionId(extension->id()) &&
401 (include_everything ||
402 ExtensionPrefs::Get(profile_)->NeedsSync(extension->id()))) {
396 sync_data_list->push_back(CreateSyncData(*extension)); 403 sync_data_list->push_back(CreateSyncData(*extension));
397 } 404 }
398 } 405 }
399 } 406 }
400 407
401 bool ExtensionSyncService::ApplyExtensionSyncDataHelper( 408 bool ExtensionSyncService::ApplyExtensionSyncDataHelper(
402 const ExtensionSyncData& extension_sync_data, 409 const ExtensionSyncData& extension_sync_data,
403 syncer::ModelType type) { 410 syncer::ModelType type) {
404 const std::string& id = extension_sync_data.id(); 411 const std::string& id = extension_sync_data.id();
405 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); 412 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 // local one. Otherwise we just enable it without granting permissions. If 448 // local one. Otherwise we just enable it without granting permissions. If
442 // any permissions are missing, CheckPermissionsIncrease will soon disable 449 // any permissions are missing, CheckPermissionsIncrease will soon disable
443 // it again. 450 // it again.
444 bool grant_permissions = 451 bool grant_permissions =
445 extension_sync_data.supports_disable_reasons() && 452 extension_sync_data.supports_disable_reasons() &&
446 extension && (version_compare_result == 0); 453 extension && (version_compare_result == 0);
447 if (grant_permissions) 454 if (grant_permissions)
448 extension_service_->GrantPermissionsAndEnableExtension(extension); 455 extension_service_->GrantPermissionsAndEnableExtension(extension);
449 else 456 else
450 extension_service_->EnableExtension(id); 457 extension_service_->EnableExtension(id);
451 } else if (!IsPendingEnable(id)) { 458 } else {
452 int disable_reasons = extension_sync_data.disable_reasons(); 459 int disable_reasons = extension_sync_data.disable_reasons();
453 if (extension_sync_data.remote_install()) { 460 if (extension_sync_data.remote_install()) {
454 if (!(disable_reasons & Extension::DISABLE_REMOTE_INSTALL)) { 461 if (!(disable_reasons & Extension::DISABLE_REMOTE_INSTALL)) {
455 // In the non-legacy case (>=M45) where disable reasons are synced at 462 // In the non-legacy case (>=M45) where disable reasons are synced at
456 // all, DISABLE_REMOTE_INSTALL should be among them already. 463 // all, DISABLE_REMOTE_INSTALL should be among them already.
457 DCHECK(!extension_sync_data.supports_disable_reasons()); 464 DCHECK(!extension_sync_data.supports_disable_reasons());
458 disable_reasons |= Extension::DISABLE_REMOTE_INSTALL; 465 disable_reasons |= Extension::DISABLE_REMOTE_INSTALL;
459 } 466 }
460 } else if (!extension_sync_data.supports_disable_reasons()) { 467 } else if (!extension_sync_data.supports_disable_reasons()) {
461 // Legacy case (<M45), from before we synced disable reasons (see 468 // Legacy case (<M45), from before we synced disable reasons (see
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 // non-INTERNAL location. Add to pending_sync_data, even though it will 520 // non-INTERNAL location. Add to pending_sync_data, even though it will
514 // never be removed (we'll never install a syncable version of the 521 // never be removed (we'll never install a syncable version of the
515 // extension), so that GetAllSyncData() continues to send it. 522 // extension), so that GetAllSyncData() continues to send it.
516 } 523 }
517 // Track pending extensions so that we can return them in GetAllSyncData(). 524 // Track pending extensions so that we can return them in GetAllSyncData().
518 return false; 525 return false;
519 } 526 }
520 527
521 return true; 528 return true;
522 } 529 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698