15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_special_storage_policy.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/cookie_settings.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/content_settings/core/common/content_settings.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/content_settings/core/common/content_settings_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/url_constants.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::APIPermission;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using extensions::Extension;
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::SpecialStoragePolicy;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSpecialStoragePolicy::ExtensionSpecialStoragePolicy(
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CookieSettings* cookie_settings)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cookie_settings_(cookie_settings) {}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSpecialStoragePolicy::~ExtensionSpecialStoragePolicy() {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::IsStorageProtected(const GURL& origin) {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (origin.SchemeIs(extensions::kExtensionScheme))
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return protected_apps_.Contains(origin);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUnlimitedStorage))
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (origin.SchemeIs(content::kChromeDevToolsScheme) &&
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      origin.host() == chrome::kChromeUIDevToolsHost)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return unlimited_extensions_.Contains(origin);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) {
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (cookie_settings_.get() == NULL)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cookie_settings_->IsCookieSessionOnly(origin);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExtensionSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return installed_apps_.Contains(origin);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (cookie_settings_.get() == NULL)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cookie_settings_->GetDefaultCookieSetting(NULL) ==
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CONTENT_SETTING_SESSION_ONLY)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ContentSettingsForOneType entries;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_settings_->GetCookieSettings(&entries);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < entries.size(); ++i) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entries[i].setting == CONTENT_SETTING_SESSION_ONLY)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::IsFileHandler(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return file_handler_extensions_.ContainsExtension(extension_id);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) {
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::AutoLock locker(lock_);
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return isolated_extensions_.Contains(origin);
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::NeedsProtection(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->is_hosted_app() && !extension->from_bookmark();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const extensions::ExtensionSet*
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionSpecialStoragePolicy::ExtensionsProtectingOrigin(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locker(lock_);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return protected_apps_.ExtensionsContaining(origin);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSpecialStoragePolicy::GrantRightsForExtension(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(extension);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!(NeedsProtection(extension) ||
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension->permissions_data()->HasAPIPermission(
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kUnlimitedStorage) ||
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension->permissions_data()->HasAPIPermission(
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kFileBrowserHandler) ||
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        extensions::AppIsolationInfo::HasIsolatedStorage(extension) ||
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension->is_app())) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int change_flags = 0;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock locker(lock_);
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (NeedsProtection(extension) && protected_apps_.Add(extension))
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // FIXME: Does GrantRightsForExtension imply |extension| is installed?
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension->is_app())
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installed_apps_.Add(extension);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (extension->permissions_data()->HasAPIPermission(
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kUnlimitedStorage) &&
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unlimited_extensions_.Add(extension))
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (extension->permissions_data()->HasAPIPermission(
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kFileBrowserHandler))
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_handler_extensions_.Add(extension);
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (extensions::AppIsolationInfo::HasIsolatedStorage(extension))
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      isolated_extensions_.Add(extension);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (change_flags) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NotifyGranted(Extension::GetBaseURLFromExtensionId(extension->id()),
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  change_flags);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSpecialStoragePolicy::RevokeRightsForExtension(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(extension);
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!(NeedsProtection(extension) ||
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension->permissions_data()->HasAPIPermission(
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kUnlimitedStorage) ||
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension->permissions_data()->HasAPIPermission(
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kFileBrowserHandler) ||
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        extensions::AppIsolationInfo::HasIsolatedStorage(extension) ||
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension->is_app())) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int change_flags = 0;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock locker(lock_);
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (NeedsProtection(extension) && protected_apps_.Remove(extension))
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      change_flags |= SpecialStoragePolicy::STORAGE_PROTECTED;
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension->is_app())
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installed_apps_.Remove(extension);
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (extension->permissions_data()->HasAPIPermission(
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kUnlimitedStorage) &&
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unlimited_extensions_.Remove(extension))
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (extension->permissions_data()->HasAPIPermission(
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            APIPermission::kFileBrowserHandler))
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_handler_extensions_.Remove(extension);
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (extensions::AppIsolationInfo::HasIsolatedStorage(extension))
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      isolated_extensions_.Remove(extension);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (change_flags) {
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NotifyRevoked(Extension::GetBaseURLFromExtensionId(extension->id()),
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  change_flags);
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSpecialStoragePolicy::RevokeRightsForAllExtensions() {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock locker(lock_);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected_apps_.Clear();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    installed_apps_.Clear();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unlimited_extensions_.Clear();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_handler_extensions_.Clear();
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    isolated_extensions_.Clear();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NotifyCleared();
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionSpecialStoragePolicy::NotifyGranted(
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& origin,
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int change_flags) {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    BrowserThread::PostTask(
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BrowserThread::IO, FROM_HERE,
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ExtensionSpecialStoragePolicy::NotifyGranted, this,
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   origin, change_flags));
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpecialStoragePolicy::NotifyGranted(origin, change_flags);
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionSpecialStoragePolicy::NotifyRevoked(
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& origin,
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int change_flags) {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    BrowserThread::PostTask(
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BrowserThread::IO, FROM_HERE,
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ExtensionSpecialStoragePolicy::NotifyRevoked, this,
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   origin, change_flags));
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpecialStoragePolicy::NotifyRevoked(origin, change_flags);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionSpecialStoragePolicy::NotifyCleared() {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    BrowserThread::PostTask(
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BrowserThread::IO, FROM_HERE,
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&ExtensionSpecialStoragePolicy::NotifyCleared, this));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpecialStoragePolicy::NotifyCleared();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SpecialCollection helper class
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSpecialStoragePolicy::SpecialCollection::SpecialCollection() {}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSpecialStoragePolicy::SpecialCollection::~SpecialCollection() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteValues(&cached_results_);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::SpecialCollection::Contains(
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !ExtensionsContaining(origin)->is_empty();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const extensions::ExtensionSet*
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSpecialStoragePolicy::SpecialCollection::ExtensionsContaining(
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CachedResults::const_iterator found = cached_results_.find(origin);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (found != cached_results_.end())
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return found->second;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  extensions::ExtensionSet* result = new extensions::ExtensionSet();
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator iter = extensions_.begin();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*iter)->OverlapsWithOrigin(origin))
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->Insert(*iter);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cached_results_[origin] = result;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSpecialStoragePolicy::SpecialCollection::ContainsExtension(
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.Contains(extension_id);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExtensionSpecialStoragePolicy::SpecialCollection::Add(
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearCache();
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return extensions_.Insert(extension);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExtensionSpecialStoragePolicy::SpecialCollection::Remove(
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearCache();
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return extensions_.Remove(extension->id());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSpecialStoragePolicy::SpecialCollection::Clear() {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearCache();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_.Clear();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSpecialStoragePolicy::SpecialCollection::ClearCache() {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteValues(&cached_results_);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cached_results_.clear();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
291