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. 4 5#include "chrome/browser/extensions/data_deleter.h" 6 7#include "chrome/browser/extensions/extension_service.h" 8#include "chrome/browser/extensions/extension_special_storage_policy.h" 9#include "chrome/browser/extensions/extension_util.h" 10#include "chrome/browser/profiles/profile.h" 11#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" 12#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 13#include "content/public/browser/browser_context.h" 14#include "content/public/browser/browser_thread.h" 15#include "content/public/browser/site_instance.h" 16#include "content/public/browser/storage_partition.h" 17#include "extensions/browser/api/storage/storage_frontend.h" 18#include "extensions/browser/extension_prefs.h" 19#include "extensions/browser/extension_system.h" 20#include "extensions/common/constants.h" 21#include "extensions/common/extension.h" 22#include "net/url_request/url_request_context_getter.h" 23 24using base::WeakPtr; 25using content::BrowserContext; 26using content::BrowserThread; 27using content::StoragePartition; 28 29namespace extensions { 30 31namespace { 32 33// Helper function that deletes data of a given |storage_origin| in a given 34// |partition|. 35void DeleteOrigin(Profile* profile, 36 StoragePartition* partition, 37 const GURL& origin, 38 const base::Closure& callback) { 39 DCHECK_CURRENTLY_ON(BrowserThread::UI); 40 DCHECK(profile); 41 DCHECK(partition); 42 43 if (origin.SchemeIs(kExtensionScheme)) { 44 // TODO(ajwong): Cookies are not properly isolated for 45 // chrome-extension:// scheme. (http://crbug.com/158386). 46 // 47 // However, no isolated apps actually can write to kExtensionScheme 48 // origins. Thus, it is benign to delete from the 49 // RequestContextForExtensions because there's nothing stored there. We 50 // preserve this code path without checking for isolation because it's 51 // simpler than special casing. This code should go away once we merge 52 // the various URLRequestContexts (http://crbug.com/159193). 53 partition->ClearDataForOrigin( 54 ~StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE, 55 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, 56 origin, 57 profile->GetRequestContextForExtensions(), 58 callback); 59 } else { 60 // We don't need to worry about the media request context because that 61 // shares the same cookie store as the main request context. 62 partition->ClearDataForOrigin( 63 ~StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE, 64 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL, 65 origin, 66 partition->GetURLRequestContext(), 67 callback); 68 } 69} 70 71void OnNeedsToGarbageCollectIsolatedStorage(WeakPtr<ExtensionService> es, 72 const base::Closure& callback) { 73 if (es) 74 ExtensionPrefs::Get(es->profile())->SetNeedsStorageGarbageCollection(true); 75 callback.Run(); 76} 77 78} // namespace 79 80// static 81void DataDeleter::StartDeleting(Profile* profile, 82 const Extension* extension, 83 const base::Closure& callback) { 84 DCHECK(profile); 85 DCHECK(extension); 86 87 if (AppIsolationInfo::HasIsolatedStorage(extension)) { 88 BrowserContext::AsyncObliterateStoragePartition( 89 profile, 90 util::GetSiteForExtensionId(extension->id(), profile), 91 base::Bind( 92 &OnNeedsToGarbageCollectIsolatedStorage, 93 ExtensionSystem::Get(profile)->extension_service()->AsWeakPtr(), 94 callback)); 95 } else { 96 GURL launch_web_url_origin( 97 AppLaunchInfo::GetLaunchWebURL(extension).GetOrigin()); 98 99 StoragePartition* partition = BrowserContext::GetStoragePartitionForSite( 100 profile, 101 Extension::GetBaseURLFromExtensionId(extension->id())); 102 103 if (extension->is_hosted_app() && 104 !profile->GetExtensionSpecialStoragePolicy()-> 105 IsStorageProtected(launch_web_url_origin)) { 106 DeleteOrigin(profile, 107 partition, 108 launch_web_url_origin, 109 base::Bind(&base::DoNothing)); 110 } 111 DeleteOrigin(profile, partition, extension->url(), callback); 112 } 113 114 // Begin removal of the settings for the current extension. 115 // StorageFrontend may not exist in unit tests. 116 StorageFrontend* frontend = StorageFrontend::Get(profile); 117 if (frontend) 118 frontend->DeleteStorageSoon(extension->id()); 119} 120 121} // namespace extensions 122