• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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