Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/extensions/extension_info_map.h"
      6 
      7 #include "chrome/common/extensions/extension.h"
      8 #include "chrome/common/url_constants.h"
      9 #include "content/browser/browser_thread.h"
     10 
     11 namespace {
     12 
     13 static void CheckOnValidThread() {
     14   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     15 }
     16 
     17 }  // namespace
     18 
     19 ExtensionInfoMap::ExtensionInfoMap() {
     20 }
     21 
     22 ExtensionInfoMap::~ExtensionInfoMap() {
     23 }
     24 
     25 void ExtensionInfoMap::AddExtension(const Extension* extension) {
     26   CheckOnValidThread();
     27   extension_info_[extension->id()] = extension;
     28   Map::iterator iter = disabled_extension_info_.find(extension->id());
     29   if (iter != disabled_extension_info_.end())
     30     disabled_extension_info_.erase(iter);
     31 }
     32 
     33 void ExtensionInfoMap::RemoveExtension(const std::string& id,
     34     const UnloadedExtensionInfo::Reason reason) {
     35   CheckOnValidThread();
     36   Map::iterator iter = extension_info_.find(id);
     37   if (iter != extension_info_.end()) {
     38     if (reason == UnloadedExtensionInfo::DISABLE)
     39       disabled_extension_info_[id] = (*iter).second;
     40     extension_info_.erase(iter);
     41   } else if (reason != UnloadedExtensionInfo::DISABLE) {
     42     // If the extension was uninstalled, make sure it's removed from the map of
     43     // disabled extensions.
     44     disabled_extension_info_.erase(id);
     45   } else {
     46     // NOTE: This can currently happen if we receive multiple unload
     47     // notifications, e.g. setting incognito-enabled state for a
     48     // disabled extension (e.g., via sync).  See
     49     // http://code.google.com/p/chromium/issues/detail?id=50582 .
     50     NOTREACHED() << id;
     51   }
     52 }
     53 
     54 
     55 std::string ExtensionInfoMap::GetNameForExtension(const std::string& id) const {
     56   Map::const_iterator iter = extension_info_.find(id);
     57   if (iter != extension_info_.end())
     58     return iter->second->name();
     59   else
     60     return std::string();
     61 }
     62 
     63 FilePath ExtensionInfoMap::GetPathForExtension(const std::string& id) const {
     64   Map::const_iterator iter = extension_info_.find(id);
     65   if (iter != extension_info_.end())
     66     return iter->second->path();
     67   else
     68     return FilePath();
     69 }
     70 
     71 FilePath ExtensionInfoMap::GetPathForDisabledExtension(
     72     const std::string& id) const {
     73   Map::const_iterator iter = disabled_extension_info_.find(id);
     74   if (iter != disabled_extension_info_.end())
     75     return iter->second->path();
     76   else
     77     return FilePath();
     78 }
     79 
     80 bool ExtensionInfoMap::ExtensionHasWebExtent(const std::string& id) const {
     81   Map::const_iterator iter = extension_info_.find(id);
     82   return iter != extension_info_.end() &&
     83       !iter->second->web_extent().is_empty();
     84 }
     85 
     86 bool ExtensionInfoMap::ExtensionCanLoadInIncognito(
     87     const std::string& id) const {
     88   Map::const_iterator iter = extension_info_.find(id);
     89   // Only split-mode extensions can load in incognito profiles.
     90   return iter != extension_info_.end() && iter->second->incognito_split_mode();
     91 }
     92 
     93 std::string ExtensionInfoMap::GetDefaultLocaleForExtension(
     94     const std::string& id) const {
     95   Map::const_iterator iter = extension_info_.find(id);
     96   std::string result;
     97   if (iter != extension_info_.end())
     98     result = iter->second->default_locale();
     99 
    100   return result;
    101 }
    102 
    103 ExtensionExtent ExtensionInfoMap::GetEffectiveHostPermissionsForExtension(
    104     const std::string& id) const {
    105   Map::const_iterator iter = extension_info_.find(id);
    106   ExtensionExtent result;
    107   if (iter != extension_info_.end())
    108     result = iter->second->GetEffectiveHostPermissions();
    109 
    110   return result;
    111 }
    112 
    113 bool ExtensionInfoMap::CheckURLAccessToExtensionPermission(
    114     const GURL& url,
    115     const char* permission_name) const {
    116   Map::const_iterator info;
    117   if (url.SchemeIs(chrome::kExtensionScheme)) {
    118     // If the url is an extension scheme, we just look it up by extension id.
    119     std::string id = url.host();
    120     info = extension_info_.find(id);
    121   } else {
    122     // Otherwise, we scan for a matching extent. Overlapping extents are
    123     // disallowed, so only one will match.
    124     info = extension_info_.begin();
    125     while (info != extension_info_.end() &&
    126            !info->second->web_extent().ContainsURL(url))
    127       ++info;
    128   }
    129 
    130   if (info == extension_info_.end())
    131     return false;
    132 
    133   return info->second->api_permissions().count(permission_name) != 0;
    134 }
    135 
    136 bool ExtensionInfoMap::URLIsForExtensionIcon(const GURL& url) const {
    137   DCHECK(url.SchemeIs(chrome::kExtensionScheme));
    138 
    139   Map::const_iterator iter = extension_info_.find(url.host());
    140   if (iter == extension_info_.end()) {
    141     iter = disabled_extension_info_.find(url.host());
    142     if (iter == disabled_extension_info_.end())
    143       return false;
    144   }
    145 
    146   std::string path = url.path();
    147   DCHECK(path.length() > 0 && path[0] == '/');
    148   path = path.substr(1);
    149   return iter->second->icons().ContainsPath(path);
    150 }
    151