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
CheckOnValidThread()13 static void CheckOnValidThread() {
14 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
15 }
16
17 } // namespace
18
ExtensionInfoMap()19 ExtensionInfoMap::ExtensionInfoMap() {
20 }
21
~ExtensionInfoMap()22 ExtensionInfoMap::~ExtensionInfoMap() {
23 }
24
AddExtension(const Extension * extension)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
RemoveExtension(const std::string & id,const UnloadedExtensionInfo::Reason reason)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
GetNameForExtension(const std::string & id) const55 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
GetPathForExtension(const std::string & id) const63 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
GetPathForDisabledExtension(const std::string & id) const71 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
ExtensionHasWebExtent(const std::string & id) const80 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
ExtensionCanLoadInIncognito(const std::string & id) const86 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
GetDefaultLocaleForExtension(const std::string & id) const93 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
GetEffectiveHostPermissionsForExtension(const std::string & id) const103 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
CheckURLAccessToExtensionPermission(const GURL & url,const char * permission_name) const113 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
URLIsForExtensionIcon(const GURL & url) const136 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