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/browsing_data/browsing_data_appcache_helper.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "chrome/browser/browsing_data/browsing_data_helper.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/common/url_constants.h" 12 #include "content/public/browser/browser_context.h" 13 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/storage_partition.h" 15 #include "webkit/browser/appcache/appcache_database.h" 16 #include "webkit/browser/appcache/appcache_storage.h" 17 18 using content::BrowserThread; 19 using content::BrowserContext; 20 21 BrowsingDataAppCacheHelper::BrowsingDataAppCacheHelper(Profile* profile) 22 : is_fetching_(false), 23 appcache_service_(BrowserContext::GetDefaultStoragePartition(profile)-> 24 GetAppCacheService()) { 25 } 26 27 void BrowsingDataAppCacheHelper::StartFetching(const base::Closure& callback) { 28 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 29 DCHECK(!is_fetching_); 30 DCHECK_EQ(false, callback.is_null()); 31 is_fetching_ = true; 32 info_collection_ = new appcache::AppCacheInfoCollection; 33 completion_callback_ = callback; 34 BrowserThread::PostTask( 35 BrowserThread::IO, FROM_HERE, 36 base::Bind(&BrowsingDataAppCacheHelper::StartFetching, this, callback)); 37 return; 38 } 39 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 41 appcache_info_callback_.Reset( 42 base::Bind(&BrowsingDataAppCacheHelper::OnFetchComplete, 43 base::Unretained(this))); 44 appcache_service_->GetAllAppCacheInfo(info_collection_.get(), 45 appcache_info_callback_.callback()); 46 } 47 48 void BrowsingDataAppCacheHelper::DeleteAppCacheGroup( 49 const GURL& manifest_url) { 50 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 51 BrowserThread::PostTask( 52 BrowserThread::IO, FROM_HERE, 53 base::Bind(&BrowsingDataAppCacheHelper::DeleteAppCacheGroup, this, 54 manifest_url)); 55 return; 56 } 57 58 appcache_service_->DeleteAppCacheGroup(manifest_url, 59 net::CompletionCallback()); 60 } 61 62 BrowsingDataAppCacheHelper::~BrowsingDataAppCacheHelper() {} 63 64 void BrowsingDataAppCacheHelper::OnFetchComplete(int rv) { 65 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { 66 // Filter out appcache info entries for non-websafe schemes. Extension state 67 // and DevTools, for example, are not considered browsing data. 68 typedef std::map<GURL, appcache::AppCacheInfoVector> InfoByOrigin; 69 InfoByOrigin& origin_map = info_collection_->infos_by_origin; 70 for (InfoByOrigin::iterator origin = origin_map.begin(); 71 origin != origin_map.end();) { 72 InfoByOrigin::iterator current = origin; 73 ++origin; 74 if (!BrowsingDataHelper::HasWebScheme(current->first)) 75 origin_map.erase(current); 76 } 77 78 BrowserThread::PostTask( 79 BrowserThread::UI, FROM_HERE, 80 base::Bind(&BrowsingDataAppCacheHelper::OnFetchComplete, this, rv)); 81 return; 82 } 83 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 85 DCHECK(is_fetching_); 86 is_fetching_ = false; 87 completion_callback_.Run(); 88 completion_callback_.Reset(); 89 } 90 91 CannedBrowsingDataAppCacheHelper::CannedBrowsingDataAppCacheHelper( 92 Profile* profile) 93 : BrowsingDataAppCacheHelper(profile), 94 profile_(profile) { 95 info_collection_ = new appcache::AppCacheInfoCollection; 96 } 97 98 CannedBrowsingDataAppCacheHelper* CannedBrowsingDataAppCacheHelper::Clone() { 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 100 CannedBrowsingDataAppCacheHelper* clone = 101 new CannedBrowsingDataAppCacheHelper(profile_); 102 103 clone->info_collection_->infos_by_origin = info_collection_->infos_by_origin; 104 return clone; 105 } 106 107 void CannedBrowsingDataAppCacheHelper::AddAppCache(const GURL& manifest_url) { 108 if (!BrowsingDataHelper::HasWebScheme(manifest_url)) 109 return; // Ignore non-websafe schemes. 110 111 OriginAppCacheInfoMap& origin_map = info_collection_->infos_by_origin; 112 appcache::AppCacheInfoVector& appcache_infos_ = 113 origin_map[manifest_url.GetOrigin()]; 114 115 for (appcache::AppCacheInfoVector::iterator 116 appcache = appcache_infos_.begin(); appcache != appcache_infos_.end(); 117 ++appcache) { 118 if (appcache->manifest_url == manifest_url) 119 return; 120 } 121 122 appcache::AppCacheInfo info; 123 info.manifest_url = manifest_url; 124 appcache_infos_.push_back(info); 125 } 126 127 void CannedBrowsingDataAppCacheHelper::Reset() { 128 info_collection_->infos_by_origin.clear(); 129 } 130 131 bool CannedBrowsingDataAppCacheHelper::empty() const { 132 return info_collection_->infos_by_origin.empty(); 133 } 134 135 size_t CannedBrowsingDataAppCacheHelper::GetAppCacheCount() const { 136 size_t count = 0; 137 const OriginAppCacheInfoMap& map = info_collection_->infos_by_origin; 138 for (OriginAppCacheInfoMap::const_iterator it = map.begin(); 139 it != map.end(); 140 ++it) { 141 count += it->second.size(); 142 } 143 return count; 144 } 145 146 const BrowsingDataAppCacheHelper::OriginAppCacheInfoMap& 147 CannedBrowsingDataAppCacheHelper::GetOriginAppCacheInfoMap() const { 148 return info_collection_->infos_by_origin; 149 } 150 151 void CannedBrowsingDataAppCacheHelper::StartFetching( 152 const base::Closure& completion_callback) { 153 completion_callback.Run(); 154 } 155 156 CannedBrowsingDataAppCacheHelper::~CannedBrowsingDataAppCacheHelper() {} 157