Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |