1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be 3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file. 4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/extensions/extension_info_map.h" 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/common/extensions/extension.h" 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/url_constants.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace { 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic void CheckOnValidThread() { 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace 18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 19731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionInfoMap::ExtensionInfoMap() { 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 22731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionInfoMap::~ExtensionInfoMap() { 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ExtensionInfoMap::AddExtension(const Extension* extension) { 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CheckOnValidThread(); 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch extension_info_[extension->id()] = extension; 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Map::iterator iter = disabled_extension_info_.find(extension->id()); 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter != disabled_extension_info_.end()) 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen disabled_extension_info_.erase(iter); 31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExtensionInfoMap::RemoveExtension(const std::string& id, 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const UnloadedExtensionInfo::Reason reason) { 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CheckOnValidThread(); 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::iterator iter = extension_info_.find(id); 37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (iter != extension_info_.end()) { 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (reason == UnloadedExtensionInfo::DISABLE) 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen disabled_extension_info_[id] = (*iter).second; 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick extension_info_.erase(iter); 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (reason != UnloadedExtensionInfo::DISABLE) { 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the extension was uninstalled, make sure it's removed from the map of 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // disabled extensions. 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen disabled_extension_info_.erase(id); 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // NOTE: This can currently happen if we receive multiple unload 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // notifications, e.g. setting incognito-enabled state for a 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // disabled extension (e.g., via sync). See 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // http://code.google.com/p/chromium/issues/detail?id=50582 . 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NOTREACHED() << id; 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string ExtensionInfoMap::GetNameForExtension(const std::string& id) const { 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(id); 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (iter != extension_info_.end()) 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return iter->second->name(); 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick else 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return std::string(); 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 63731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFilePath ExtensionInfoMap::GetPathForExtension(const std::string& id) const { 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(id); 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (iter != extension_info_.end()) 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return iter->second->path(); 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick else 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FilePath(); 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFilePath ExtensionInfoMap::GetPathForDisabledExtension( 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& id) const { 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Map::const_iterator iter = disabled_extension_info_.find(id); 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter != disabled_extension_info_.end()) 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return iter->second->path(); 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return FilePath(); 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionInfoMap::ExtensionHasWebExtent(const std::string& id) const { 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(id); 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return iter != extension_info_.end() && 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !iter->second->web_extent().is_empty(); 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionInfoMap::ExtensionCanLoadInIncognito( 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& id) const { 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(id); 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Only split-mode extensions can load in incognito profiles. 90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return iter != extension_info_.end() && iter->second->incognito_split_mode(); 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string ExtensionInfoMap::GetDefaultLocaleForExtension( 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& id) const { 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(id); 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string result; 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (iter != extension_info_.end()) 98513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result = iter->second->default_locale(); 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return result; 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 103731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionExtent ExtensionInfoMap::GetEffectiveHostPermissionsForExtension( 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& id) const { 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(id); 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ExtensionExtent result; 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (iter != extension_info_.end()) 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result = iter->second->GetEffectiveHostPermissions(); 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return result; 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionInfoMap::CheckURLAccessToExtensionPermission( 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& url, 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const char* permission_name) const { 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator info; 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (url.SchemeIs(chrome::kExtensionScheme)) { 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If the url is an extension scheme, we just look it up by extension id. 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string id = url.host(); 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick info = extension_info_.find(id); 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Otherwise, we scan for a matching extent. Overlapping extents are 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // disallowed, so only one will match. 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick info = extension_info_.begin(); 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick while (info != extension_info_.end() && 126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !info->second->web_extent().ContainsURL(url)) 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ++info; 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (info == extension_info_.end()) 131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return info->second->api_permissions().count(permission_name) != 0; 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ExtensionInfoMap::URLIsForExtensionIcon(const GURL& url) const { 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(url.SchemeIs(chrome::kExtensionScheme)); 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Map::const_iterator iter = extension_info_.find(url.host()); 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter == extension_info_.end()) { 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter = disabled_extension_info_.find(url.host()); 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter == disabled_extension_info_.end()) 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string path = url.path(); 147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(path.length() > 0 && path[0] == '/'); 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick path = path.substr(1); 149513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return iter->second->icons().ContainsPath(path); 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 151