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 11namespace { 12 13static void CheckOnValidThread() { 14 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 15} 16 17} // namespace 18 19ExtensionInfoMap::ExtensionInfoMap() { 20} 21 22ExtensionInfoMap::~ExtensionInfoMap() { 23} 24 25void 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 33void 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 55std::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 63FilePath 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 71FilePath 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 80bool 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 86bool 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 93std::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 103ExtensionExtent 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 113bool 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 136bool 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