extension_sync_service.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_service.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <iterator>
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/basictypes.h"
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/app_sync_data.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_error_ui.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_data.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_service_factory.h"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_util.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/launch_util.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/sync/glue/sync_start_util.h"
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/sync/sync_prefs.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/common/extensions/sync_helper.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/app_sorting.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/feature_switch.h"
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/manifest_constants.h"
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "sync/api/sync_change.h"
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "sync/api/sync_error_factory.h"
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::Extension;
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::ExtensionPrefs;
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionRegistry;
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using extensions::FeatureSwitch;
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ExtensionSyncService::ExtensionSyncService(Profile* profile,
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                           ExtensionPrefs* extension_prefs,
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                           ExtensionService* extension_service)
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : profile_(profile),
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_prefs_(extension_prefs),
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_service_(extension_service),
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      app_sync_bundle_(this),
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_sync_bundle_(this),
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_app_enables_(
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          make_scoped_ptr(new browser_sync::SyncPrefs(
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              extension_prefs_->pref_service())),
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          &app_sync_bundle_,
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          syncer::APPS),
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_extension_enables_(
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          make_scoped_ptr(new browser_sync::SyncPrefs(
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              extension_prefs_->pref_service())),
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          &extension_sync_bundle_,
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          syncer::EXTENSIONS) {
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SetSyncStartFlare(sync_start_util::GetFlareForSyncableService(
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      profile_->GetPath()));
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extension_service_->set_extension_sync_service(this);
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extension_prefs_->app_sorting()->SetExtensionSyncService(this);
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ExtensionSyncService::~ExtensionSyncService() {}
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ExtensionSyncService* ExtensionSyncService::Get(Profile* profile) {
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return ExtensionSyncServiceFactory::GetForProfile(profile);
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)syncer::SyncChange ExtensionSyncService::PrepareToSyncUninstallExtension(
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const extensions::Extension* extension, bool extensions_ready) {
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Extract the data we need for sync now, but don't actually sync until we've
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // completed the uninstallation.
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(tim): If we get here and IsSyncing is false, this will cause
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // "back from the dead" style bugs, because sync will add-back the extension
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // that was uninstalled here when MergeDataAndStartSyncing is called.
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // See crbug.com/256795.
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extensions::sync_helper::IsSyncableApp(extension)) {
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (app_sync_bundle_.IsSyncing())
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return app_sync_bundle_.CreateSyncChangeToDelete(extension);
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    else if (extensions_ready && !flare_.is_null())
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      flare_.Run(syncer::APPS);  // Tell sync to start ASAP.
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (extensions::sync_helper::IsSyncableExtension(extension)) {
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (extension_sync_bundle_.IsSyncing())
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return extension_sync_bundle_.CreateSyncChangeToDelete(extension);
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    else if (extensions_ready && !flare_.is_null())
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      flare_.Run(syncer::EXTENSIONS);  // Tell sync to start ASAP.
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return syncer::SyncChange();
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::ProcessSyncUninstallExtension(
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::string& extension_id,
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const syncer::SyncChange& sync_change) {
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (app_sync_bundle_.HasExtensionId(extension_id) &&
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      sync_change.sync_data().GetDataType() == syncer::APPS) {
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    app_sync_bundle_.ProcessDeletion(extension_id, sync_change);
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (extension_sync_bundle_.HasExtensionId(extension_id) &&
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)             sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) {
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension_sync_bundle_.ProcessDeletion(extension_id, sync_change);
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::SyncEnableExtension(
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const extensions::Extension& extension) {
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Syncing may not have started yet, so handle pending enables.
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extensions::sync_helper::IsSyncableApp(&extension))
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_app_enables_.OnExtensionEnabled(extension.id());
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extensions::sync_helper::IsSyncableExtension(&extension))
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_extension_enables_.OnExtensionEnabled(extension.id());
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SyncExtensionChangeIfNeeded(extension);
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::SyncDisableExtension(
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const extensions::Extension& extension) {
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Syncing may not have started yet, so handle pending enables.
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extensions::sync_helper::IsSyncableApp(&extension))
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_app_enables_.OnExtensionDisabled(extension.id());
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extensions::sync_helper::IsSyncableExtension(&extension))
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pending_extension_enables_.OnExtensionDisabled(extension.id());
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SyncExtensionChangeIfNeeded(extension);
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)syncer::SyncMergeResult ExtensionSyncService::MergeDataAndStartSyncing(
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    syncer::ModelType type,
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const syncer::SyncDataList& initial_sync_data,
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(sync_processor.get());
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CHECK(sync_error_factory.get());
1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  switch (type) {
1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case syncer::EXTENSIONS:
1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_sync_bundle_.SetupSync(sync_processor.release(),
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                       sync_error_factory.release(),
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                       initial_sync_data);
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_extension_enables_.OnSyncStarted(extension_service_);
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      break;
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case syncer::APPS:
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      app_sync_bundle_.SetupSync(sync_processor.release(),
1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                 sync_error_factory.release(),
1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                 initial_sync_data);
1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_app_enables_.OnSyncStarted(extension_service_);
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      break;
1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    default:
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      LOG(FATAL) << "Got " << type << " ModelType";
1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Process local extensions.
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(yoz): Determine whether pending extensions should be considered too.
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  //            See crbug.com/104399.
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  syncer::SyncDataList sync_data_list = GetAllSyncData(type);
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  syncer::SyncChangeList sync_change_list;
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (syncer::SyncDataList::const_iterator i = sync_data_list.begin();
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       i != sync_data_list.end();
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       ++i) {
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    switch (type) {
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        case syncer::EXTENSIONS:
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          sync_change_list.push_back(
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              extension_sync_bundle_.CreateSyncChange(*i));
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          break;
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        case syncer::APPS:
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          sync_change_list.push_back(app_sync_bundle_.CreateSyncChange(*i));
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          break;
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      default:
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        LOG(FATAL) << "Got " << type << " ModelType";
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == syncer::EXTENSIONS) {
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension_sync_bundle_.ProcessSyncChangeList(sync_change_list);
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (type == syncer::APPS) {
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    app_sync_bundle_.ProcessSyncChangeList(sync_change_list);
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return syncer::SyncMergeResult(type);
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::StopSyncing(syncer::ModelType type) {
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == syncer::APPS) {
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    app_sync_bundle_.Reset();
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (type == syncer::EXTENSIONS) {
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension_sync_bundle_.Reset();
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)syncer::SyncDataList ExtensionSyncService::GetAllSyncData(
1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    syncer::ModelType type) const {
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == syncer::EXTENSIONS)
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return extension_sync_bundle_.GetAllSyncData();
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == syncer::APPS)
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return app_sync_bundle_.GetAllSyncData();
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We should only get sync data for extensions and apps.
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NOTREACHED();
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return syncer::SyncDataList();
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)syncer::SyncError ExtensionSyncService::ProcessSyncChanges(
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const tracked_objects::Location& from_here,
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const syncer::SyncChangeList& change_list) {
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (syncer::SyncChangeList::const_iterator i = change_list.begin();
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      i != change_list.end();
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ++i) {
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    syncer::ModelType type = i->sync_data().GetDataType();
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (type == syncer::EXTENSIONS) {
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_sync_bundle_.ProcessSyncChange(
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          extensions::ExtensionSyncData(*i));
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else if (type == syncer::APPS) {
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      app_sync_bundle_.ProcessSyncChange(extensions::AppSyncData(*i));
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  extension_prefs_->app_sorting()->FixNTPOrdinalCollisions();
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return syncer::SyncError();
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)extensions::ExtensionSyncData ExtensionSyncService::GetExtensionSyncData(
2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const Extension& extension) const {
2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return extensions::ExtensionSyncData(
2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension,
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_service_->IsExtensionEnabled(extension.id()),
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::util::IsIncognitoEnabled(extension.id(), profile_));
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)extensions::AppSyncData ExtensionSyncService::GetAppSyncData(
2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const Extension& extension) const {
2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return extensions::AppSyncData(
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension,
2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_service_->IsExtensionEnabled(extension.id()),
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::util::IsIncognitoEnabled(extension.id(), profile_),
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_prefs_->app_sorting()->GetAppLaunchOrdinal(extension.id()),
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_prefs_->app_sorting()->GetPageOrdinal(extension.id()),
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::GetLaunchTypePrefValue(extension_prefs_, extension.id()));
2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)std::vector<extensions::ExtensionSyncData>
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ExtensionSyncService::GetExtensionSyncDataList() const {
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<extensions::ExtensionSyncData> extension_sync_list;
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extension_sync_bundle_.GetExtensionSyncDataListHelper(
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->enabled_extensions(), &extension_sync_list);
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extension_sync_bundle_.GetExtensionSyncDataListHelper(
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->disabled_extensions(), &extension_sync_list);
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extension_sync_bundle_.GetExtensionSyncDataListHelper(
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->terminated_extensions(), &extension_sync_list);
2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<extensions::ExtensionSyncData> pending_extensions =
2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_sync_bundle_.GetPendingData();
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extension_sync_list.insert(extension_sync_list.begin(),
2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             pending_extensions.begin(),
2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             pending_extensions.end());
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return extension_sync_list;
2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)std::vector<extensions::AppSyncData> ExtensionSyncService::GetAppSyncDataList()
2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<extensions::AppSyncData> app_sync_list;
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  app_sync_bundle_.GetAppSyncDataListHelper(
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->enabled_extensions(), &app_sync_list);
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  app_sync_bundle_.GetAppSyncDataListHelper(
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->disabled_extensions(), &app_sync_list);
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  app_sync_bundle_.GetAppSyncDataListHelper(
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry->terminated_extensions(), &app_sync_list);
2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<extensions::AppSyncData> pending_apps =
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      app_sync_bundle_.GetPendingData();
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  app_sync_list.insert(app_sync_list.begin(),
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       pending_apps.begin(),
2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       pending_apps.end());
2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return app_sync_list;
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ExtensionSyncService::ProcessExtensionSyncData(
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const extensions::ExtensionSyncData& extension_sync_data) {
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!ProcessExtensionSyncDataHelper(extension_sync_data,
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      syncer::EXTENSIONS)) {
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension_sync_bundle_.AddPendingExtension(extension_sync_data.id(),
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                               extension_sync_data);
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension_service_->CheckForUpdatesSoon();
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return true;
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ExtensionSyncService::ProcessAppSyncData(
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const extensions::AppSyncData& app_sync_data) {
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const std::string& id = app_sync_data.id();
3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (app_sync_data.app_launch_ordinal().IsValid() &&
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      app_sync_data.page_ordinal().IsValid()) {
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    extension_prefs_->app_sorting()->SetAppLaunchOrdinal(
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        id,
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        app_sync_data.app_launch_ordinal());
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    extension_prefs_->app_sorting()->SetPageOrdinal(
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        id,
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        app_sync_data.page_ordinal());
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The corresponding validation of this value during AppSyncData population
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // is in AppSyncData::PopulateAppSpecifics.
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (app_sync_data.launch_type() >= extensions::LAUNCH_TYPE_FIRST &&
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      app_sync_data.launch_type() < extensions::NUM_LAUNCH_TYPES) {
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensions::SetLaunchType(extension_service_, id,
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              app_sync_data.launch_type());
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!ProcessExtensionSyncDataHelper(app_sync_data.extension_sync_data(),
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                      syncer::APPS)) {
3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    app_sync_bundle_.AddPendingApp(id, app_sync_data);
3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extension_service_->CheckForUpdatesSoon();
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return true;
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::SyncOrderingChange(const std::string& extension_id) {
3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const extensions::Extension* ext = extension_service_->GetInstalledExtension(
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_id);
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (ext)
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SyncExtensionChangeIfNeeded(*ext);
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::SetSyncStartFlare(
3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const syncer::SyncableService::StartSyncFlare& flare) {
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  flare_ = flare;
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ExtensionSyncService::IsCorrectSyncType(const Extension& extension,
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                         syncer::ModelType type) const {
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == syncer::EXTENSIONS &&
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::sync_helper::IsSyncableExtension(&extension)) {
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == syncer::APPS &&
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extensions::sync_helper::IsSyncableApp(&extension)) {
3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return false;
3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ExtensionSyncService::IsPendingEnable(
3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const std::string& extension_id) const {
3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return pending_app_enables_.Contains(extension_id) ||
3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      pending_extension_enables_.Contains(extension_id);
3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ExtensionSyncService::ProcessExtensionSyncDataHelper(
3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const extensions::ExtensionSyncData& extension_sync_data,
3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    syncer::ModelType type) {
3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const std::string& id = extension_sync_data.id();
3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const Extension* extension = extension_service_->GetInstalledExtension(id);
3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(bolms): we should really handle this better.  The particularly bad
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // case is where an app becomes an extension or vice versa, and we end up with
3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // a zombie extension that won't go away.
3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extension && !IsCorrectSyncType(*extension, type))
3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Handle uninstalls first.
3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extension_sync_data.uninstalled()) {
3811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!extension_service_->UninstallExtensionHelper(extension_service_, id)) {
3821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      LOG(WARNING) << "Could not uninstall extension " << id
3831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                   << " for sync";
3841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
3851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
3861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Extension from sync was uninstalled by the user as external extensions.
3891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Honor user choice and skip installation/enabling.
3901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extension_service_->IsExternalExtensionUninstalled(id)) {
3911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    LOG(WARNING) << "Extension with id " << id
3921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 << " from sync was uninstalled as external extension";
3931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
3941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Set user settings.
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the extension has been disabled from sync, it may not have
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // been installed yet, so we don't know if the disable reason was a
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // permissions increase.  That will be updated once CheckPermissionsIncrease
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // is called for it.
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension_sync_data.enabled())
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    extension_service_->EnableExtension(id);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  else if (!IsPendingEnable(id))
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    extension_service_->DisableExtension(
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        id, Extension::DISABLE_UNKNOWN_FROM_SYNC);
4061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // We need to cache some version information here because setting the
4081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // incognito flag invalidates the |extension| pointer (it reloads the
4091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // extension).
4101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool extension_installed = (extension != NULL);
4111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int result = extension ?
4121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension->version()->CompareTo(extension_sync_data.version()) : 0;
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::util::SetIsIncognitoEnabled(
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      id, profile_, extension_sync_data.incognito_enabled());
4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extension = NULL;  // No longer safe to use.
4161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extension_installed) {
4181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // If the extension is already installed, check if it's outdated.
4191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (result < 0) {
4201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Extension is outdated.
4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return false;
4221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
4231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
4241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // TODO(akalin): Replace silent update with a list of enabled
4251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // permissions.
4261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const bool kInstallSilently = true;
4271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    CHECK(type == syncer::EXTENSIONS || type == syncer::APPS);
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    extensions::PendingExtensionInfo::ShouldAllowInstallPredicate filter =
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        (type == syncer::APPS) ? extensions::sync_helper::IsSyncableApp :
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                 extensions::sync_helper::IsSyncableExtension;
4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!extension_service_->pending_extension_manager()->AddFromSync(
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            id,
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            extension_sync_data.update_url(),
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            filter,
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            kInstallSilently)) {
4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      LOG(WARNING) << "Could not add pending extension for " << id;
4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // This means that the extension is already pending installation, with a
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // non-INTERNAL location.  Add to pending_sync_data, even though it will
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // never be removed (we'll never install a syncable version of the
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // extension), so that GetAllSyncData() continues to send it.
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Track pending extensions so that we can return them in GetAllSyncData().
4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return true;
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ExtensionSyncService::SyncExtensionChangeIfNeeded(
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const Extension& extension) {
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (extensions::sync_helper::IsSyncableApp(&extension)) {
4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (app_sync_bundle_.IsSyncing())
4551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      app_sync_bundle_.SyncChangeIfNeeded(extension);
4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    else if (extension_service_->is_ready() && !flare_.is_null())
4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      flare_.Run(syncer::APPS);
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (extensions::sync_helper::IsSyncableExtension(&extension)) {
4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (extension_sync_bundle_.IsSyncing())
4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      extension_sync_bundle_.SyncChangeIfNeeded(extension);
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    else if (extension_service_->is_ready() && !flare_.is_null())
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      flare_.Run(syncer::EXTENSIONS);
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
465