Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_special_storage_policy.cc
blob625805c88ea06d436ed0abf97fd7e7583c6a4c2b
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/extensions/extension_special_storage_policy.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/content_settings/cookie_settings.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/content_settings.h"
15 #include "chrome/common/content_settings_types.h"
16 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/url_constants.h"
20 #include "extensions/common/constants.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_set.h"
24 using content::BrowserThread;
25 using extensions::APIPermission;
26 using extensions::Extension;
27 using quota::SpecialStoragePolicy;
29 ExtensionSpecialStoragePolicy::ExtensionSpecialStoragePolicy(
30 CookieSettings* cookie_settings)
31 : cookie_settings_(cookie_settings) {}
33 ExtensionSpecialStoragePolicy::~ExtensionSpecialStoragePolicy() {}
35 bool ExtensionSpecialStoragePolicy::IsStorageProtected(const GURL& origin) {
36 if (origin.SchemeIs(extensions::kExtensionScheme))
37 return true;
38 base::AutoLock locker(lock_);
39 return protected_apps_.Contains(origin);
42 bool ExtensionSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) {
43 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUnlimitedStorage))
44 return true;
46 if (origin.SchemeIs(chrome::kChromeDevToolsScheme) &&
47 origin.host() == chrome::kChromeUIDevToolsHost)
48 return true;
50 base::AutoLock locker(lock_);
51 return unlimited_extensions_.Contains(origin);
54 bool ExtensionSpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) {
55 if (cookie_settings_.get() == NULL)
56 return false;
57 return cookie_settings_->IsCookieSessionOnly(origin);
60 bool ExtensionSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) {
61 return installed_apps_.Contains(origin);
64 bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
65 if (cookie_settings_.get() == NULL)
66 return false;
67 if (cookie_settings_->GetDefaultCookieSetting(NULL) ==
68 CONTENT_SETTING_SESSION_ONLY)
69 return true;
70 ContentSettingsForOneType entries;
71 cookie_settings_->GetCookieSettings(&entries);
72 for (size_t i = 0; i < entries.size(); ++i) {
73 if (entries[i].setting == CONTENT_SETTING_SESSION_ONLY)
74 return true;
76 return false;
79 bool ExtensionSpecialStoragePolicy::IsFileHandler(
80 const std::string& extension_id) {
81 base::AutoLock locker(lock_);
82 return file_handler_extensions_.ContainsExtension(extension_id);
85 bool ExtensionSpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) {
86 base::AutoLock locker(lock_);
87 return isolated_extensions_.Contains(origin);
90 bool ExtensionSpecialStoragePolicy::NeedsProtection(
91 const extensions::Extension* extension) {
92 return extension->is_hosted_app() && !extension->from_bookmark();
95 const extensions::ExtensionSet*
96 ExtensionSpecialStoragePolicy::ExtensionsProtectingOrigin(
97 const GURL& origin) {
98 base::AutoLock locker(lock_);
99 return protected_apps_.ExtensionsContaining(origin);
102 void ExtensionSpecialStoragePolicy::GrantRightsForExtension(
103 const extensions::Extension* extension) {
104 DCHECK(extension);
105 if (!(NeedsProtection(extension) ||
106 extension->HasAPIPermission(APIPermission::kUnlimitedStorage) ||
107 extension->HasAPIPermission(APIPermission::kFileBrowserHandler) ||
108 extensions::AppIsolationInfo::HasIsolatedStorage(extension) ||
109 extension->is_app())) {
110 return;
113 int change_flags = 0;
115 base::AutoLock locker(lock_);
116 if (NeedsProtection(extension) && protected_apps_.Add(extension))
117 change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED;
118 // FIXME: Does GrantRightsForExtension imply |extension| is installed?
119 if (extension->is_app())
120 installed_apps_.Add(extension);
122 if (extension->HasAPIPermission(APIPermission::kUnlimitedStorage) &&
123 unlimited_extensions_.Add(extension))
124 change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
126 if (extension->HasAPIPermission(APIPermission::kFileBrowserHandler))
127 file_handler_extensions_.Add(extension);
129 if (extensions::AppIsolationInfo::HasIsolatedStorage(extension))
130 isolated_extensions_.Add(extension);
133 if (change_flags) {
134 NotifyGranted(Extension::GetBaseURLFromExtensionId(extension->id()),
135 change_flags);
139 void ExtensionSpecialStoragePolicy::RevokeRightsForExtension(
140 const extensions::Extension* extension) {
141 DCHECK(extension);
142 if (!(NeedsProtection(extension) ||
143 extension->HasAPIPermission(APIPermission::kUnlimitedStorage) ||
144 extension->HasAPIPermission(APIPermission::kFileBrowserHandler) ||
145 extensions::AppIsolationInfo::HasIsolatedStorage(extension) ||
146 extension->is_app())) {
147 return;
149 int change_flags = 0;
151 base::AutoLock locker(lock_);
152 if (NeedsProtection(extension) && protected_apps_.Remove(extension))
153 change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED;
155 if (extension->is_app())
156 installed_apps_.Remove(extension);
158 if (extension->HasAPIPermission(APIPermission::kUnlimitedStorage) &&
159 unlimited_extensions_.Remove(extension))
160 change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
162 if (extension->HasAPIPermission(APIPermission::kFileBrowserHandler))
163 file_handler_extensions_.Remove(extension);
165 if (extensions::AppIsolationInfo::HasIsolatedStorage(extension))
166 isolated_extensions_.Remove(extension);
169 if (change_flags) {
170 NotifyRevoked(Extension::GetBaseURLFromExtensionId(extension->id()),
171 change_flags);
175 void ExtensionSpecialStoragePolicy::RevokeRightsForAllExtensions() {
177 base::AutoLock locker(lock_);
178 protected_apps_.Clear();
179 installed_apps_.Clear();
180 unlimited_extensions_.Clear();
181 file_handler_extensions_.Clear();
182 isolated_extensions_.Clear();
185 NotifyCleared();
188 void ExtensionSpecialStoragePolicy::NotifyGranted(
189 const GURL& origin,
190 int change_flags) {
191 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
192 BrowserThread::PostTask(
193 BrowserThread::IO, FROM_HERE,
194 base::Bind(&ExtensionSpecialStoragePolicy::NotifyGranted, this,
195 origin, change_flags));
196 return;
198 SpecialStoragePolicy::NotifyGranted(origin, change_flags);
201 void ExtensionSpecialStoragePolicy::NotifyRevoked(
202 const GURL& origin,
203 int change_flags) {
204 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
205 BrowserThread::PostTask(
206 BrowserThread::IO, FROM_HERE,
207 base::Bind(&ExtensionSpecialStoragePolicy::NotifyRevoked, this,
208 origin, change_flags));
209 return;
211 SpecialStoragePolicy::NotifyRevoked(origin, change_flags);
214 void ExtensionSpecialStoragePolicy::NotifyCleared() {
215 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
216 BrowserThread::PostTask(
217 BrowserThread::IO, FROM_HERE,
218 base::Bind(&ExtensionSpecialStoragePolicy::NotifyCleared, this));
219 return;
221 SpecialStoragePolicy::NotifyCleared();
224 //-----------------------------------------------------------------------------
225 // SpecialCollection helper class
226 //-----------------------------------------------------------------------------
228 ExtensionSpecialStoragePolicy::SpecialCollection::SpecialCollection() {}
230 ExtensionSpecialStoragePolicy::SpecialCollection::~SpecialCollection() {
231 STLDeleteValues(&cached_results_);
234 bool ExtensionSpecialStoragePolicy::SpecialCollection::Contains(
235 const GURL& origin) {
236 return !ExtensionsContaining(origin)->is_empty();
239 const extensions::ExtensionSet*
240 ExtensionSpecialStoragePolicy::SpecialCollection::ExtensionsContaining(
241 const GURL& origin) {
242 CachedResults::const_iterator found = cached_results_.find(origin);
243 if (found != cached_results_.end())
244 return found->second;
246 extensions::ExtensionSet* result = new extensions::ExtensionSet();
247 for (extensions::ExtensionSet::const_iterator iter = extensions_.begin();
248 iter != extensions_.end(); ++iter) {
249 if ((*iter)->OverlapsWithOrigin(origin))
250 result->Insert(*iter);
252 cached_results_[origin] = result;
253 return result;
256 bool ExtensionSpecialStoragePolicy::SpecialCollection::ContainsExtension(
257 const std::string& extension_id) {
258 return extensions_.Contains(extension_id);
261 bool ExtensionSpecialStoragePolicy::SpecialCollection::Add(
262 const extensions::Extension* extension) {
263 ClearCache();
264 return extensions_.Insert(extension);
267 bool ExtensionSpecialStoragePolicy::SpecialCollection::Remove(
268 const extensions::Extension* extension) {
269 ClearCache();
270 return extensions_.Remove(extension->id());
273 void ExtensionSpecialStoragePolicy::SpecialCollection::Clear() {
274 ClearCache();
275 extensions_.Clear();
278 void ExtensionSpecialStoragePolicy::SpecialCollection::ClearCache() {
279 STLDeleteValues(&cached_results_);
280 cached_results_.clear();