summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 21:19:28 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 21:19:28 +0000
commitf3d3b3843becc02b010ebbcf4087850c215f3ebc (patch)
tree5ea8398d29e2e80bcb5990abe9048104f025e6fe /chrome
parent05f1464c3ce00020d596f7da07254c4f83bef3a2 (diff)
downloadchromium_src-f3d3b3843becc02b010ebbcf4087850c215f3ebc.zip
chromium_src-f3d3b3843becc02b010ebbcf4087850c215f3ebc.tar.gz
chromium_src-f3d3b3843becc02b010ebbcf4087850c215f3ebc.tar.bz2
Remove the last c/b/e/extension_service.h includes from src/extensions
This breaks another unwanted dependency from src/extensions back to src/chrome. * Move PendingExtensionManager and PendingExtensionInfo back into chrome, as they are tied to the concepts of extension install/update and we have decided to keep that functionality in chrome for now. * Eliminate unused include in extension_function.cc No functional changes. BUG=none TEST=compiles TBR=zea@chromium.org for header file move touching chrome/browser/sync/test/integration/sync_extension_helper.cc Review URL: https://codereview.chromium.org/195763017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257203 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/extension_service.cc2
-rw-r--r--chrome/browser/extensions/extension_service.h2
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc4
-rw-r--r--chrome/browser/extensions/pending_extension_info.cc68
-rw-r--r--chrome/browser/extensions/pending_extension_info.h95
-rw-r--r--chrome/browser/extensions/pending_extension_manager.cc280
-rw-r--r--chrome/browser/extensions/pending_extension_manager.h155
-rw-r--r--chrome/browser/extensions/updater/extension_updater.cc2
-rw-r--r--chrome/browser/sync/test/integration/sync_extension_helper.cc4
-rw-r--r--chrome/browser/ui/ash/app_sync_ui_state.cc2
-rw-r--r--chrome/chrome_browser_extensions.gypi4
11 files changed, 610 insertions, 8 deletions
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index a74de00..992d262 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -44,6 +44,7 @@
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/extensions/installed_loader.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/extensions/permissions_updater.h"
#include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/extensions/updater/extension_cache.h"
@@ -78,7 +79,6 @@
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/external_provider_interface.h"
#include "extensions/browser/management_policy.h"
-#include "extensions/browser/pending_extension_manager.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_map.h"
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 48ff38a..52fab6b 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -20,6 +20,7 @@
#include "base/strings/string16.h"
#include "chrome/browser/extensions/blacklist.h"
#include "chrome/browser/extensions/extension_sync_service.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/common/extensions/extension_constants.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/notification_observer.h"
@@ -28,7 +29,6 @@
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/external_provider_interface.h"
#include "extensions/browser/management_policy.h"
-#include "extensions/browser/pending_extension_manager.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index ab5bfe9..29da632 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -55,6 +55,8 @@
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/extensions/installed_loader.h"
#include "chrome/browser/extensions/pack_extension_job.h"
+#include "chrome/browser/extensions/pending_extension_info.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/extensions/test_blacklist.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/extensions/unpacked_installer.h"
@@ -91,8 +93,6 @@
#include "extensions/browser/extension_system.h"
#include "extensions/browser/external_provider_interface.h"
#include "extensions/browser/management_policy.h"
-#include "extensions/browser/pending_extension_info.h"
-#include "extensions/browser/pending_extension_manager.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/test_management_policy.h"
#include "extensions/common/constants.h"
diff --git a/chrome/browser/extensions/pending_extension_info.cc b/chrome/browser/extensions/pending_extension_info.cc
new file mode 100644
index 0000000..bb0d452
--- /dev/null
+++ b/chrome/browser/extensions/pending_extension_info.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/pending_extension_info.h"
+
+#include "base/logging.h"
+
+namespace extensions {
+
+PendingExtensionInfo::PendingExtensionInfo(
+ const std::string& id,
+ const GURL& update_url,
+ const Version& version,
+ ShouldAllowInstallPredicate should_allow_install,
+ bool is_from_sync,
+ bool install_silently,
+ Manifest::Location install_source,
+ int creation_flags,
+ bool mark_acknowledged)
+ : id_(id),
+ update_url_(update_url),
+ version_(version),
+ should_allow_install_(should_allow_install),
+ is_from_sync_(is_from_sync),
+ install_silently_(install_silently),
+ install_source_(install_source),
+ creation_flags_(creation_flags),
+ mark_acknowledged_(mark_acknowledged) {}
+
+PendingExtensionInfo::PendingExtensionInfo()
+ : update_url_(),
+ should_allow_install_(NULL),
+ is_from_sync_(true),
+ install_silently_(false),
+ install_source_(Manifest::INVALID_LOCATION) {}
+
+bool PendingExtensionInfo::operator==(const PendingExtensionInfo& rhs) const {
+ return id_ == rhs.id_;
+}
+
+int PendingExtensionInfo::CompareTo(const PendingExtensionInfo& other) const {
+ DCHECK_EQ(id_, other.id_);
+ if (version_.IsValid() && other.version_.IsValid()) {
+ int comparison = version_.CompareTo(other.version_);
+
+ // If the versions differ then return the version comparison result.
+ if (comparison != 0)
+ return comparison;
+ }
+
+ // The versions aren't specified, or they are the same version. Check
+ // the install source.
+ if (install_source_ == other.install_source_) {
+ // Same install source, so |this| has the same precedence as |other|.
+ return 0;
+ }
+
+ // Different install sources; |this| has higher precedence if
+ // |install_source_| is the higher priority source.
+ Manifest::Location higher_priority_source =
+ Manifest::GetHigherPriorityLocation(
+ install_source_, other.install_source_);
+
+ return higher_priority_source == install_source_ ? 1 : -1;
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/pending_extension_info.h b/chrome/browser/extensions/pending_extension_info.h
new file mode 100644
index 0000000..fd803bd
--- /dev/null
+++ b/chrome/browser/extensions/pending_extension_info.h
@@ -0,0 +1,95 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_PENDING_EXTENSION_INFO_H_
+#define CHROME_BROWSER_EXTENSIONS_PENDING_EXTENSION_INFO_H_
+
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "base/version.h"
+#include "extensions/common/manifest.h"
+#include "url/gurl.h"
+
+FORWARD_DECLARE_TEST(ExtensionServiceTest, AddPendingExtensionFromSync);
+
+namespace extensions {
+class Extension;
+
+// A pending extension is an extension that hasn't been installed yet
+// and is intended to be installed in the next auto-update cycle. The
+// update URL of a pending extension may be blank, in which case a
+// default one is assumed.
+// TODO(skerner): Make this class an implementation detail of
+// PendingExtensionManager, and remove all other users.
+class PendingExtensionInfo {
+ public:
+ typedef bool (*ShouldAllowInstallPredicate)(const Extension*);
+
+ PendingExtensionInfo(
+ const std::string& id,
+ const GURL& update_url,
+ const Version& version,
+ ShouldAllowInstallPredicate should_allow_install,
+ bool is_from_sync,
+ bool install_silently,
+ Manifest::Location install_source,
+ int creation_flags,
+ bool mark_acknowledged);
+
+ // Required for STL container membership. Should not be used directly.
+ PendingExtensionInfo();
+
+ // Consider two PendingExtensionInfos equal if their ids are equal.
+ bool operator==(const PendingExtensionInfo& rhs) const;
+
+ const std::string& id() const { return id_; }
+ const GURL& update_url() const { return update_url_; }
+ const Version& version() const { return version_; }
+
+ // ShouldAllowInstall() returns the result of running constructor argument
+ // |should_allow_install| on an extension. After an extension is unpacked,
+ // this function is run. If it returns true, the extension is installed.
+ // If not, the extension is discarded. This allows creators of
+ // PendingExtensionInfo objects to ensure that extensions meet some criteria
+ // that can only be tested once the extension is unpacked.
+ bool ShouldAllowInstall(const Extension* extension) const {
+ return should_allow_install_(extension);
+ }
+ bool is_from_sync() const { return is_from_sync_; }
+ bool install_silently() const { return install_silently_; }
+ Manifest::Location install_source() const { return install_source_; }
+ int creation_flags() const { return creation_flags_; }
+ bool mark_acknowledged() const { return mark_acknowledged_; }
+
+ // Returns -1, 0 or 1 if |this| has lower, equal or higher precedence than
+ // |other|, respectively. "Equal" precedence means that the version and the
+ // install source match. "Higher" precedence means that the version is newer,
+ // or the version matches but the install source has higher priority.
+ // It is only valid to invoke this when the ids match.
+ int CompareTo(const PendingExtensionInfo& other) const;
+
+ private:
+ std::string id_;
+
+ GURL update_url_;
+ Version version_;
+
+ // When the extension is about to be installed, this function is
+ // called. If this function returns true, the install proceeds. If
+ // this function returns false, the install is aborted.
+ ShouldAllowInstallPredicate should_allow_install_;
+
+ bool is_from_sync_; // This update check was initiated from sync.
+ bool install_silently_;
+ Manifest::Location install_source_;
+ int creation_flags_;
+ bool mark_acknowledged_;
+
+ FRIEND_TEST_ALL_PREFIXES(::ExtensionServiceTest, AddPendingExtensionFromSync);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_PENDING_EXTENSION_INFO_H_
diff --git a/chrome/browser/extensions/pending_extension_manager.cc b/chrome/browser/extensions/pending_extension_manager.cc
new file mode 100644
index 0000000..e2a636d
--- /dev/null
+++ b/chrome/browser/extensions/pending_extension_manager.cc
@@ -0,0 +1,280 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/pending_extension_manager.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/version.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/common/extension.h"
+#include "url/gurl.h"
+
+using content::BrowserThread;
+
+namespace {
+
+// Install predicate used by AddFromExternalUpdateUrl().
+bool AlwaysInstall(const extensions::Extension* extension) {
+ return true;
+}
+
+std::string GetVersionString(const Version& version) {
+ return version.IsValid() ? version.GetString() : "invalid";
+}
+
+} // namespace
+
+namespace extensions {
+
+PendingExtensionManager::PendingExtensionManager(
+ const ExtensionServiceInterface& service)
+ : service_(service) {
+}
+
+PendingExtensionManager::~PendingExtensionManager() {}
+
+const PendingExtensionInfo* PendingExtensionManager::GetById(
+ const std::string& id) const {
+ PendingExtensionList::const_iterator iter;
+ for (iter = pending_extension_list_.begin();
+ iter != pending_extension_list_.end();
+ ++iter) {
+ if (id == iter->id())
+ return &(*iter);
+ }
+
+ return NULL;
+}
+
+bool PendingExtensionManager::Remove(const std::string& id) {
+ PendingExtensionList::iterator iter;
+ for (iter = pending_extension_list_.begin();
+ iter != pending_extension_list_.end();
+ ++iter) {
+ if (id == iter->id()) {
+ pending_extension_list_.erase(iter);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PendingExtensionManager::IsIdPending(const std::string& id) const {
+ return GetById(id) != NULL;
+}
+
+bool PendingExtensionManager::HasPendingExtensions() const {
+ return !pending_extension_list_.empty();
+}
+
+bool PendingExtensionManager::HasPendingExtensionFromSync() const {
+ PendingExtensionList::const_iterator iter;
+ for (iter = pending_extension_list_.begin();
+ iter != pending_extension_list_.end();
+ ++iter) {
+ if (iter->is_from_sync())
+ return true;
+ }
+
+ return false;
+}
+
+bool PendingExtensionManager::AddFromSync(
+ const std::string& id,
+ const GURL& update_url,
+ PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
+ bool install_silently) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (service_.GetInstalledExtension(id)) {
+ LOG(ERROR) << "Trying to add pending extension " << id
+ << " which already exists";
+ return false;
+ }
+
+ // Make sure we don't ever try to install the CWS app, because even though
+ // it is listed as a syncable app (because its values need to be synced) it
+ // should already be installed on every instance.
+ if (id == extension_misc::kWebStoreAppId) {
+ NOTREACHED();
+ return false;
+ }
+
+ const bool kIsFromSync = true;
+ const Manifest::Location kSyncLocation = Manifest::INTERNAL;
+ const bool kMarkAcknowledged = false;
+
+ return AddExtensionImpl(id, update_url, Version(), should_allow_install,
+ kIsFromSync, install_silently, kSyncLocation,
+ Extension::NO_FLAGS, kMarkAcknowledged);
+}
+
+bool PendingExtensionManager::AddFromExtensionImport(
+ const std::string& id,
+ const GURL& update_url,
+ PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (service_.GetInstalledExtension(id)) {
+ LOG(ERROR) << "Trying to add pending extension " << id
+ << " which already exists";
+ return false;
+ }
+
+ const bool kIsFromSync = false;
+ const bool kInstallSilently = true;
+ const Manifest::Location kManifestLocation = Manifest::INTERNAL;
+ const bool kMarkAcknowledged = false;
+
+ return AddExtensionImpl(id, update_url, Version(), should_allow_install,
+ kIsFromSync, kInstallSilently, kManifestLocation,
+ Extension::NO_FLAGS, kMarkAcknowledged);
+}
+
+bool PendingExtensionManager::AddFromExternalUpdateUrl(
+ const std::string& id,
+ const GURL& update_url,
+ Manifest::Location location,
+ int creation_flags,
+ bool mark_acknowledged) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ const bool kIsFromSync = false;
+ const bool kInstallSilently = true;
+
+ const Extension* extension = service_.GetInstalledExtension(id);
+ if (extension &&
+ location == Manifest::GetHigherPriorityLocation(location,
+ extension->location())) {
+ // If the new location has higher priority than the location of an existing
+ // extension, let the update process overwrite the existing extension.
+ } else {
+ if (service_.IsExternalExtensionUninstalled(id))
+ return false;
+
+ if (extension) {
+ LOG(DFATAL) << "Trying to add extension " << id
+ << " by external update, but it is already installed.";
+ return false;
+ }
+ }
+
+ return AddExtensionImpl(id, update_url, Version(), &AlwaysInstall,
+ kIsFromSync, kInstallSilently,
+ location, creation_flags, mark_acknowledged);
+}
+
+
+bool PendingExtensionManager::AddFromExternalFile(
+ const std::string& id,
+ Manifest::Location install_source,
+ const Version& version,
+ int creation_flags,
+ bool mark_acknowledged) {
+ // TODO(skerner): AddFromSync() checks to see if the extension is
+ // installed, but this method assumes that the caller already
+ // made sure it is not installed. Make all AddFrom*() methods
+ // consistent.
+ GURL kUpdateUrl = GURL();
+ bool kIsFromSync = false;
+ bool kInstallSilently = true;
+
+ return AddExtensionImpl(
+ id,
+ kUpdateUrl,
+ version,
+ &AlwaysInstall,
+ kIsFromSync,
+ kInstallSilently,
+ install_source,
+ creation_flags,
+ mark_acknowledged);
+}
+
+void PendingExtensionManager::GetPendingIdsForUpdateCheck(
+ std::list<std::string>* out_ids_for_update_check) const {
+ PendingExtensionList::const_iterator iter;
+ for (iter = pending_extension_list_.begin();
+ iter != pending_extension_list_.end();
+ ++iter) {
+ Manifest::Location install_source = iter->install_source();
+
+ // Some install sources read a CRX from the filesystem. They can
+ // not be fetched from an update URL, so don't include them in the
+ // set of ids.
+ if (install_source == Manifest::EXTERNAL_PREF ||
+ install_source == Manifest::EXTERNAL_REGISTRY)
+ continue;
+
+ out_ids_for_update_check->push_back(iter->id());
+ }
+}
+
+bool PendingExtensionManager::AddExtensionImpl(
+ const std::string& id,
+ const GURL& update_url,
+ const Version& version,
+ PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
+ bool is_from_sync,
+ bool install_silently,
+ Manifest::Location install_source,
+ int creation_flags,
+ bool mark_acknowledged) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ PendingExtensionInfo info(id,
+ update_url,
+ version,
+ should_allow_install,
+ is_from_sync,
+ install_silently,
+ install_source,
+ creation_flags,
+ mark_acknowledged);
+
+ if (const PendingExtensionInfo* pending = GetById(id)) {
+ // Bugs in this code will manifest as sporadic incorrect extension
+ // locations in situations where multiple install sources run at the
+ // same time. For example, on first login to a chrome os machine, an
+ // extension may be requested by sync and the default extension set.
+ // The following logging will help diagnose such issues.
+ VLOG(1) << "Extension id " << id
+ << " was entered for update more than once."
+ << " old location: " << pending->install_source()
+ << " new location: " << install_source
+ << " old version: " << GetVersionString(pending->version())
+ << " new version: " << GetVersionString(version);
+
+ // Never override an existing extension with an older version. Only
+ // extensions from local CRX files have a known version; extensions from an
+ // update URL will get the latest version.
+
+ // If |pending| has the same or higher precedence than |info| then don't
+ // install |info| over |pending|.
+ if (pending->CompareTo(info) >= 0)
+ return false;
+
+ VLOG(1) << "Overwrite existing record.";
+
+ std::replace(pending_extension_list_.begin(),
+ pending_extension_list_.end(),
+ *pending,
+ info);
+ } else {
+ pending_extension_list_.push_back(info);
+ }
+
+ return true;
+}
+
+void PendingExtensionManager::AddForTesting(
+ const PendingExtensionInfo& pending_extension_info) {
+ pending_extension_list_.push_back(pending_extension_info);
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/pending_extension_manager.h b/chrome/browser/extensions/pending_extension_manager.h
new file mode 100644
index 0000000..4c3572c
--- /dev/null
+++ b/chrome/browser/extensions/pending_extension_manager.h
@@ -0,0 +1,155 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_PENDING_EXTENSION_MANAGER_H_
+#define CHROME_BROWSER_EXTENSIONS_PENDING_EXTENSION_MANAGER_H_
+
+#include <list>
+#include <string>
+
+#include "chrome/browser/extensions/pending_extension_info.h"
+#include "extensions/common/manifest.h"
+
+class ExtensionServiceInterface;
+class GURL;
+
+namespace base {
+class Version;
+}
+
+FORWARD_DECLARE_TEST(ExtensionServiceTest,
+ UpdatePendingExtensionAlreadyInstalled);
+
+namespace extensions {
+class Extension;
+class PendingExtensionManager;
+
+class ExtensionUpdaterTest;
+void SetupPendingExtensionManagerForTest(
+ int count, const GURL& update_url,
+ PendingExtensionManager* pending_extension_manager);
+
+// Class PendingExtensionManager manages the set of extensions which are
+// being installed or updated. In general, installation and updates take
+// time, because they involve downloading, unpacking, and installing.
+// This class allows us to avoid race cases where multiple sources install
+// the same extension.
+// The extensions service creates an instance of this class, and manages
+// its lifetime. This class should only be used from the UI thread.
+class PendingExtensionManager {
+ public:
+ // |service| is a reference to the ExtensionService whose pending
+ // extensions we are managing. The service creates an instance of
+ // this class on construction, and destroys it on destruction.
+ // The service remains valid over the entire lifetime of this class.
+ explicit PendingExtensionManager(const ExtensionServiceInterface& service);
+ ~PendingExtensionManager();
+
+ // TODO(skerner): Many of these methods can be private once code in
+ // ExtensionService is moved into methods of this class.
+
+ // Remove extension with id |id| from the set of pending extensions. Returns
+ // true if such an extension was found and removed, false otherwise.
+ bool Remove(const std::string& id);
+
+ // Get the information for a pending extension. Returns a pointer to the
+ // pending extension with id |id|, or NULL if there is no such extension.
+ const PendingExtensionInfo* GetById(const std::string& id) const;
+
+ // Is |id| in the set of pending extensions?
+ bool IsIdPending(const std::string& id) const;
+
+ // Returns true if there are any extensions pending.
+ bool HasPendingExtensions() const;
+
+ // Whether there is pending extension install from sync.
+ bool HasPendingExtensionFromSync() const;
+
+ // Adds an extension in a pending state; the extension with the
+ // given info will be installed on the next auto-update cycle.
+ // Return true if the extension was added. Will return false
+ // if the extension is pending from another source which overrides
+ // sync installs (such as a policy extension) or if the extension
+ // is already installed.
+ //
+ // TODO(akalin): Replace |install_silently| with a list of
+ // pre-enabled permissions.
+ bool AddFromSync(
+ const std::string& id,
+ const GURL& update_url,
+ PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
+ bool install_silently);
+
+ // Adds an extension that was depended on by another extension.
+ bool AddFromExtensionImport(
+ const std::string& id,
+ const GURL& update_url,
+ PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install);
+
+ // Given an extension id and an update URL, schedule the extension
+ // to be fetched, installed, and activated.
+ bool AddFromExternalUpdateUrl(const std::string& id,
+ const GURL& update_url,
+ Manifest::Location location,
+ int creation_flags,
+ bool mark_acknowledged);
+
+ // Add a pending extension record for an external CRX file.
+ // Return true if the CRX should be installed, false if an existing
+ // pending record overrides it.
+ bool AddFromExternalFile(
+ const std::string& id,
+ Manifest::Location location,
+ const base::Version& version,
+ int creation_flags,
+ bool mark_acknowledged);
+
+ // Get the list of pending IDs that should be installed from an update URL.
+ // Pending extensions that will be installed from local files will not be
+ // included in the set.
+ void GetPendingIdsForUpdateCheck(
+ std::list<std::string>* out_ids_for_update_check) const;
+
+ private:
+ typedef std::list<PendingExtensionInfo> PendingExtensionList;
+
+ // Assumes an extension with id |id| is not already installed.
+ // Return true if the extension was added.
+ bool AddExtensionImpl(
+ const std::string& id,
+ const GURL& update_url,
+ const base::Version& version,
+ PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
+ bool is_from_sync,
+ bool install_silently,
+ Manifest::Location install_source,
+ int creation_flags,
+ bool mark_acknowledged);
+
+ // Add a pending extension record directly. Used for unit tests that need
+ // to set an inital state. Use friendship to allow the tests to call this
+ // method.
+ void AddForTesting(const PendingExtensionInfo& pending_extension_info);
+
+ // Reference to the extension service whose pending extensions this class is
+ // managing. Because this class is a member of |service_|, it is created
+ // and destroyed with |service_|. We only use methods from the interface
+ // ExtensionServiceInterface.
+ const ExtensionServiceInterface& service_;
+
+ PendingExtensionList pending_extension_list_;
+
+ FRIEND_TEST_ALL_PREFIXES(::ExtensionServiceTest,
+ UpdatePendingExtensionAlreadyInstalled);
+ friend class ExtensionUpdaterTest;
+ friend void SetupPendingExtensionManagerForTest(
+ int count, const GURL& update_url,
+ PendingExtensionManager* pending_extension_manager);
+
+ DISALLOW_COPY_AND_ASSIGN(PendingExtensionManager);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_PENDING_EXTENSION_MANAGER_H_
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc
index 523614f..45f1ab8 100644
--- a/chrome/browser/extensions/updater/extension_updater.cc
+++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/extensions/api/module/module.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/extensions/updater/extension_downloader.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
@@ -29,7 +30,6 @@
#include "content/public/browser/notification_source.h"
#include "crypto/sha2.h"
#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/pending_extension_manager.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
diff --git a/chrome/browser/sync/test/integration/sync_extension_helper.cc b/chrome/browser/sync/test/integration/sync_extension_helper.cc
index 7355503..6e09377 100644
--- a/chrome/browser/sync/test/integration/sync_extension_helper.cc
+++ b/chrome/browser/sync/test/integration/sync_extension_helper.cc
@@ -10,13 +10,13 @@
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_util.h"
+#include "chrome/browser/extensions/pending_extension_info.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
-#include "extensions/browser/pending_extension_info.h"
-#include "extensions/browser/pending_extension_manager.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/id_util.h"
diff --git a/chrome/browser/ui/ash/app_sync_ui_state.cc b/chrome/browser/ui/ash/app_sync_ui_state.cc
index c911e4a..c3a9b3b 100644
--- a/chrome/browser/ui/ash/app_sync_ui_state.cc
+++ b/chrome/browser/ui/ash/app_sync_ui_state.cc
@@ -7,6 +7,7 @@
#include "base/prefs/pref_service.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/pending_extension_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -16,7 +17,6 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_system.h"
-#include "extensions/browser/pending_extension_manager.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user_manager.h"
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 5ffff97..ebde052 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -805,6 +805,10 @@
'browser/extensions/page_action_controller.h',
'browser/extensions/pending_enables.cc',
'browser/extensions/pending_enables.h',
+ 'browser/extensions/pending_extension_info.cc',
+ 'browser/extensions/pending_extension_info.h',
+ 'browser/extensions/pending_extension_manager.cc',
+ 'browser/extensions/pending_extension_manager.h',
'browser/extensions/permissions_updater.cc',
'browser/extensions/permissions_updater.h',
'browser/extensions/plugin_manager.cc',