1 // Copyright (c) 2010 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_appcache_helper.h" 6 7 #include "chrome/browser/net/chrome_url_request_context.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/common/url_constants.h" 10 #include "content/browser/browser_thread.h" 11 #include "webkit/appcache/appcache_database.h" 12 #include "webkit/appcache/appcache_storage.h" 13 14 using appcache::AppCacheDatabase; 15 16 BrowsingDataAppCacheHelper::BrowsingDataAppCacheHelper(Profile* profile) 17 : request_context_getter_(profile->GetRequestContext()), 18 is_fetching_(false) { 19 } 20 21 void BrowsingDataAppCacheHelper::StartFetching(Callback0::Type* callback) { 22 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 23 DCHECK(!is_fetching_); 24 DCHECK(callback); 25 is_fetching_ = true; 26 info_collection_ = new appcache::AppCacheInfoCollection; 27 completion_callback_.reset(callback); 28 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( 29 this, &BrowsingDataAppCacheHelper::StartFetching, callback)); 30 return; 31 } 32 33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 34 appcache_info_callback_ = 35 new net::CancelableCompletionCallback<BrowsingDataAppCacheHelper>( 36 this, &BrowsingDataAppCacheHelper::OnFetchComplete); 37 GetAppCacheService()->GetAllAppCacheInfo(info_collection_, 38 appcache_info_callback_); 39 } 40 41 void BrowsingDataAppCacheHelper::CancelNotification() { 42 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 43 completion_callback_.reset(); 44 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( 45 this, &BrowsingDataAppCacheHelper::CancelNotification)); 46 return; 47 } 48 49 if (appcache_info_callback_) 50 appcache_info_callback_.release()->Cancel(); 51 } 52 53 void BrowsingDataAppCacheHelper::DeleteAppCacheGroup( 54 const GURL& manifest_url) { 55 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { 56 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( 57 this, &BrowsingDataAppCacheHelper::DeleteAppCacheGroup, 58 manifest_url)); 59 return; 60 } 61 GetAppCacheService()->DeleteAppCacheGroup(manifest_url, NULL); 62 } 63 64 BrowsingDataAppCacheHelper::~BrowsingDataAppCacheHelper() {} 65 66 void BrowsingDataAppCacheHelper::OnFetchComplete(int rv) { 67 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { 68 // Filter out appache info entries for extensions. Extension state is not 69 // considered browsing data. 70 typedef std::map<GURL, appcache::AppCacheInfoVector> InfoByOrigin; 71 InfoByOrigin& origin_map = info_collection_->infos_by_origin; 72 for (InfoByOrigin::iterator origin = origin_map.begin(); 73 origin != origin_map.end();) { 74 InfoByOrigin::iterator current = origin; 75 ++origin; 76 if (current->first.SchemeIs(chrome::kExtensionScheme)) 77 origin_map.erase(current); 78 } 79 80 appcache_info_callback_ = NULL; 81 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( 82 this, &BrowsingDataAppCacheHelper::OnFetchComplete, rv)); 83 return; 84 } 85 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 87 DCHECK(is_fetching_); 88 is_fetching_ = false; 89 if (completion_callback_ != NULL) { 90 completion_callback_->Run(); 91 completion_callback_.reset(); 92 } 93 } 94 95 ChromeAppCacheService* BrowsingDataAppCacheHelper::GetAppCacheService() { 96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 97 ChromeURLRequestContext* request_context = 98 reinterpret_cast<ChromeURLRequestContext*>( 99 request_context_getter_->GetURLRequestContext()); 100 return request_context ? request_context->appcache_service() 101 : NULL; 102 } 103 104 CannedBrowsingDataAppCacheHelper::CannedBrowsingDataAppCacheHelper( 105 Profile* profile) 106 : BrowsingDataAppCacheHelper(profile), 107 profile_(profile) { 108 info_collection_ = new appcache::AppCacheInfoCollection; 109 } 110 111 CannedBrowsingDataAppCacheHelper* CannedBrowsingDataAppCacheHelper::Clone() { 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 113 CannedBrowsingDataAppCacheHelper* clone = 114 new CannedBrowsingDataAppCacheHelper(profile_); 115 116 clone->info_collection_->infos_by_origin = info_collection_->infos_by_origin; 117 return clone; 118 } 119 120 void CannedBrowsingDataAppCacheHelper::AddAppCache(const GURL& manifest_url) { 121 typedef std::map<GURL, appcache::AppCacheInfoVector> InfoByOrigin; 122 InfoByOrigin& origin_map = info_collection_->infos_by_origin; 123 appcache::AppCacheInfoVector& appcache_infos_ = 124 origin_map[manifest_url.GetOrigin()]; 125 126 for (appcache::AppCacheInfoVector::iterator 127 appcache = appcache_infos_.begin(); appcache != appcache_infos_.end(); 128 ++appcache) { 129 if (appcache->manifest_url == manifest_url) 130 return; 131 } 132 133 appcache::AppCacheInfo info; 134 info.manifest_url = manifest_url; 135 appcache_infos_.push_back(info); 136 } 137 138 void CannedBrowsingDataAppCacheHelper::Reset() { 139 info_collection_->infos_by_origin.clear(); 140 } 141 142 bool CannedBrowsingDataAppCacheHelper::empty() const { 143 return info_collection_->infos_by_origin.empty(); 144 } 145 146 void CannedBrowsingDataAppCacheHelper::StartFetching( 147 Callback0::Type* completion_callback) { 148 completion_callback->Run(); 149 delete completion_callback; 150 } 151 152 CannedBrowsingDataAppCacheHelper::~CannedBrowsingDataAppCacheHelper() {} 153