[Extensions] Add GetInstalledExtension() method to ExtensionService

Extend GetExtensionByIdInternal() to handle terminated
extensions.

Make ExtensionService and PendingExtensionManager use
GetInstalledExtension().

BUG=80752
TEST=

Review URL: http://codereview.chromium.org/6901079

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83380 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 621a1bb..df2f793 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -399,9 +399,7 @@
     const std::string& extension_id) {
 
   const Extension* extension =
-      extensions_service->GetExtensionById(extension_id, true);
-  if (!extension)
-    extension = extensions_service->GetTerminatedExtension(extension_id);
+      extensions_service->GetInstalledExtension(extension_id);
 
   // We can't call UninstallExtension with an invalid extension ID.
   if (!extension) {
@@ -549,7 +547,7 @@
 
 const Extension* ExtensionService::GetExtensionById(
     const std::string& id, bool include_disabled) const {
-  return GetExtensionByIdInternal(id, true, include_disabled);
+  return GetExtensionByIdInternal(id, true, include_disabled, false);
 }
 
 void ExtensionService::Init() {
@@ -581,7 +579,8 @@
   bool is_pending_extension = pending_extension_manager_.GetById(
       id, &pending_extension_info);
 
-  const Extension* extension = GetExtensionByIdInternal(id, true, true);
+  const Extension* extension =
+      GetExtensionByIdInternal(id, true, true, false);
   if (!is_pending_extension && !extension) {
     LOG(WARNING) << "Will not update extension " << id
                  << " because it is not installed or pending";
@@ -660,10 +659,7 @@
                                           std::string* error) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  const Extension* extension =
-      GetExtensionByIdInternal(extension_id, true, true);
-  if (!extension)
-    extension = GetTerminatedExtension(extension_id);
+  const Extension* extension = GetInstalledExtension(extension_id);
 
   // Callers should not send us nonexistent extensions.
   CHECK(extension);
@@ -756,7 +752,7 @@
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   const Extension* extension =
-      GetExtensionByIdInternal(extension_id, false, true);
+      GetExtensionByIdInternal(extension_id, false, true, false);
   if (!extension)
     return;
 
@@ -783,7 +779,7 @@
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   const Extension* extension =
-      GetExtensionByIdInternal(extension_id, true, false);
+      GetExtensionByIdInternal(extension_id, true, false, false);
   // The extension may have been disabled already.
   if (!extension)
     return;
@@ -1336,7 +1332,8 @@
     return;
   }
 
-  const Extension* extension = GetExtensionByIdInternal(id, true, true);
+  const Extension* extension =
+      GetExtensionByIdInternal(id, true, true, false);
   // TODO(akalin): Figure out what to do with terminated extensions.
 
   // Handle already-installed extensions (just update settings).
@@ -1529,7 +1526,7 @@
     UnloadedExtensionInfo::Reason reason) {
   // Make sure the extension gets deleted after we return from this function.
   scoped_refptr<const Extension> extension(
-      GetExtensionByIdInternal(extension_id, true, true));
+      GetExtensionByIdInternal(extension_id, true, true, false));
 
   // This method can be called via PostTask, so the extension may have been
   // unloaded by the time this runs.
@@ -1718,7 +1715,7 @@
   // extension once again includes "omnibox" in an upgrade, the extension
   // can upgrade without requiring this user's approval.
   const Extension* old = GetExtensionByIdInternal(extension->id(),
-                                                  true, true);
+                                                  true, true, false);
   bool granted_full_access;
   std::set<std::string> granted_apis;
   ExtensionExtent granted_extent;
@@ -1872,7 +1869,8 @@
 }
 
 const Extension* ExtensionService::GetExtensionByIdInternal(
-    const std::string& id, bool include_enabled, bool include_disabled) const {
+    const std::string& id, bool include_enabled, bool include_disabled,
+    bool include_terminated) const {
   std::string lowercase_id = StringToLowerASCII(id);
   if (include_enabled) {
     for (ExtensionList::const_iterator iter = extensions_.begin();
@@ -1888,6 +1886,13 @@
         return *iter;
     }
   }
+  if (include_terminated) {
+    for (ExtensionList::const_iterator iter = terminated_extensions_.begin();
+        iter != terminated_extensions_.end(); ++iter) {
+      if ((*iter)->id() == lowercase_id)
+        return *iter;
+    }
+  }
   return NULL;
 }
 
@@ -1911,14 +1916,13 @@
 }
 
 const Extension* ExtensionService::GetTerminatedExtension(
-    const std::string& id) {
-  std::string lowercase_id = StringToLowerASCII(id);
-  for (ExtensionList::const_iterator iter = terminated_extensions_.begin();
-       iter != terminated_extensions_.end(); ++iter) {
-    if ((*iter)->id() == lowercase_id)
-      return *iter;
-  }
-  return NULL;
+    const std::string& id) const {
+  return GetExtensionByIdInternal(id, false, false, true);
+}
+
+const Extension* ExtensionService::GetInstalledExtension(
+    const std::string& id) const {
+  return GetExtensionByIdInternal(id, true, true, true);
 }
 
 const Extension* ExtensionService::GetWebStoreApp() {
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 5898605..76e506c 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -68,6 +68,8 @@
                                const GURL& download_url) = 0;
   virtual const Extension* GetExtensionById(const std::string& id,
                                             bool include_disabled) const = 0;
+  virtual const Extension* GetInstalledExtension(
+      const std::string& id) const = 0;
 
   virtual bool IsExtensionEnabled(const std::string& extension_id) const = 0;
   virtual bool IsExternalExtensionUninstalled(
@@ -235,13 +237,18 @@
   // Start up the extension event routers.
   void InitEventRouters();
 
-  // Look up an extension by ID.
+  // Look up an extension by ID.  Does not include terminated
+  // extensions.
   virtual const Extension* GetExtensionById(
       const std::string& id, bool include_disabled) const OVERRIDE;
 
-  // Looks up a terminated (crashed) extension by ID. GetExtensionById does
-  // not include terminated extensions.
-  virtual const Extension* GetTerminatedExtension(const std::string& id);
+  // Looks up a terminated (crashed) extension by ID.
+  const Extension* GetTerminatedExtension(const std::string& id) const;
+
+  // Looks up an extension by ID, regardless of whether it's enabled,
+  // disabled, or terminated.
+  virtual const Extension* GetInstalledExtension(
+      const std::string& id) const OVERRIDE;
 
   // Updates a currently-installed extension with the contents from
   // |extension_path|.
@@ -521,7 +528,8 @@
   // and disabled extensions.
   const Extension* GetExtensionByIdInternal(const std::string& id,
                                             bool include_enabled,
-                                            bool include_disabled) const;
+                                            bool include_disabled,
+                                            bool include_terminated) const;
 
 
   // Keep track of terminated extensions.
diff --git a/chrome/browser/extensions/pending_extension_manager.cc b/chrome/browser/extensions/pending_extension_manager.cc
index 28bcaa6e..21c3a05 100644
--- a/chrome/browser/extensions/pending_extension_manager.cc
+++ b/chrome/browser/extensions/pending_extension_manager.cc
@@ -60,7 +60,7 @@
     bool enable_incognito_on_install) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  if (service_.GetExtensionById(id, true)) {
+  if (service_.GetInstalledExtension(id)) {
     LOG(ERROR) << "Trying to add pending extension " << id
                << " which already exists";
     return false;
@@ -89,7 +89,7 @@
   if (service_.IsExternalExtensionUninstalled(id))
     return;
 
-  if (service_.GetExtensionById(id, true)) {
+  if (service_.GetInstalledExtension(id)) {
     LOG(DFATAL) << "Trying to add extension " << id
                 << " by external update, but it is already installed.";
     return;
diff --git a/chrome/browser/extensions/test_extension_service.cc b/chrome/browser/extensions/test_extension_service.cc
index 46e7544c..a997e83a 100644
--- a/chrome/browser/extensions/test_extension_service.cc
+++ b/chrome/browser/extensions/test_extension_service.cc
@@ -30,6 +30,12 @@
   return NULL;
 }
 
+const Extension* TestExtensionService::GetInstalledExtension(
+    const std::string& id) const {
+  ADD_FAILURE();
+  return NULL;
+}
+
 bool TestExtensionService::IsExtensionEnabled(
     const std::string& extension_id) const {
   ADD_FAILURE();
diff --git a/chrome/browser/extensions/test_extension_service.h b/chrome/browser/extensions/test_extension_service.h
index 9f18b16..b535d19 100644
--- a/chrome/browser/extensions/test_extension_service.h
+++ b/chrome/browser/extensions/test_extension_service.h
@@ -26,6 +26,8 @@
                                const GURL& download_url) OVERRIDE;
   virtual const Extension* GetExtensionById(
       const std::string& id, bool include_disabled) const OVERRIDE;
+  virtual const Extension* GetInstalledExtension(
+      const std::string& id) const OVERRIDE;
   virtual bool IsExtensionEnabled(
       const std::string& extension_id) const OVERRIDE;
   virtual bool IsExternalExtensionUninstalled(