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