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
[email protected] 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
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