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_database_helper.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "base/file_util.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "chrome/browser/browsing_data/browsing_data_helper.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/storage_partition.h" 16 #include "net/base/completion_callback.h" 17 #include "net/base/net_errors.h" 18 #include "webkit/common/database/database_identifier.h" 19 20 using content::BrowserContext; 21 using content::BrowserThread; 22 using webkit_database::DatabaseIdentifier; 23 24 BrowsingDataDatabaseHelper::DatabaseInfo::DatabaseInfo( 25 const DatabaseIdentifier& identifier, 26 const std::string& database_name, 27 const std::string& description, 28 int64 size, 29 base::Time last_modified) 30 : identifier(identifier), 31 database_name(database_name), 32 description(description), 33 size(size), 34 last_modified(last_modified) { 35 } 36 37 BrowsingDataDatabaseHelper::DatabaseInfo::~DatabaseInfo() {} 38 39 BrowsingDataDatabaseHelper::BrowsingDataDatabaseHelper(Profile* profile) 40 : is_fetching_(false), 41 tracker_(BrowserContext:: 42 GetDefaultStoragePartition(profile)->GetDatabaseTracker()) { 43 } 44 45 BrowsingDataDatabaseHelper::~BrowsingDataDatabaseHelper() { 46 } 47 48 void BrowsingDataDatabaseHelper::StartFetching( 49 const base::Callback<void(const std::list<DatabaseInfo>&)>& callback) { 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 51 DCHECK(!is_fetching_); 52 DCHECK_EQ(false, callback.is_null()); 53 54 is_fetching_ = true; 55 database_info_.clear(); 56 completion_callback_ = callback; 57 BrowserThread::PostTask( 58 BrowserThread::FILE, FROM_HERE, 59 base::Bind(&BrowsingDataDatabaseHelper::FetchDatabaseInfoOnFileThread, 60 this)); 61 } 62 63 void BrowsingDataDatabaseHelper::DeleteDatabase(const std::string& origin, 64 const std::string& name) { 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 66 BrowserThread::PostTask( 67 BrowserThread::FILE, FROM_HERE, 68 base::Bind(&BrowsingDataDatabaseHelper::DeleteDatabaseOnFileThread, this, 69 origin, name)); 70 } 71 72 void BrowsingDataDatabaseHelper::FetchDatabaseInfoOnFileThread() { 73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 74 std::vector<webkit_database::OriginInfo> origins_info; 75 if (tracker_.get() && tracker_->GetAllOriginsInfo(&origins_info)) { 76 for (std::vector<webkit_database::OriginInfo>::const_iterator ori = 77 origins_info.begin(); ori != origins_info.end(); ++ori) { 78 DatabaseIdentifier identifier = 79 DatabaseIdentifier::Parse(ori->GetOriginIdentifier()); 80 if (!BrowsingDataHelper::HasWebScheme(identifier.ToOrigin())) { 81 // Non-websafe state is not considered browsing data. 82 continue; 83 } 84 std::vector<base::string16> databases; 85 ori->GetAllDatabaseNames(&databases); 86 for (std::vector<base::string16>::const_iterator db = databases.begin(); 87 db != databases.end(); ++db) { 88 base::FilePath file_path = 89 tracker_->GetFullDBFilePath(ori->GetOriginIdentifier(), *db); 90 base::PlatformFileInfo file_info; 91 if (base::GetFileInfo(file_path, &file_info)) { 92 database_info_.push_back(DatabaseInfo( 93 identifier, 94 UTF16ToUTF8(*db), 95 UTF16ToUTF8(ori->GetDatabaseDescription(*db)), 96 file_info.size, 97 file_info.last_modified)); 98 } 99 } 100 } 101 } 102 103 BrowserThread::PostTask( 104 BrowserThread::UI, FROM_HERE, 105 base::Bind(&BrowsingDataDatabaseHelper::NotifyInUIThread, this)); 106 } 107 108 void BrowsingDataDatabaseHelper::NotifyInUIThread() { 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 110 DCHECK(is_fetching_); 111 completion_callback_.Run(database_info_); 112 completion_callback_.Reset(); 113 is_fetching_ = false; 114 database_info_.clear(); 115 } 116 117 void BrowsingDataDatabaseHelper::DeleteDatabaseOnFileThread( 118 const std::string& origin, 119 const std::string& name) { 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 121 if (!tracker_.get()) 122 return; 123 tracker_->DeleteDatabase(origin, UTF8ToUTF16(name), 124 net::CompletionCallback()); 125 } 126 127 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::PendingDatabaseInfo( 128 const GURL& origin, 129 const std::string& name, 130 const std::string& description) 131 : origin(origin), 132 name(name), 133 description(description) { 134 } 135 136 CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::~PendingDatabaseInfo() {} 137 138 bool CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo::operator<( 139 const PendingDatabaseInfo& other) const { 140 if (origin == other.origin) 141 return name < other.name; 142 return origin < other.origin; 143 } 144 145 CannedBrowsingDataDatabaseHelper::CannedBrowsingDataDatabaseHelper( 146 Profile* profile) 147 : BrowsingDataDatabaseHelper(profile), 148 profile_(profile) { 149 } 150 151 CannedBrowsingDataDatabaseHelper* CannedBrowsingDataDatabaseHelper::Clone() { 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 153 CannedBrowsingDataDatabaseHelper* clone = 154 new CannedBrowsingDataDatabaseHelper(profile_); 155 156 clone->pending_database_info_ = pending_database_info_; 157 return clone; 158 } 159 160 void CannedBrowsingDataDatabaseHelper::AddDatabase( 161 const GURL& origin, 162 const std::string& name, 163 const std::string& description) { 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 165 if (BrowsingDataHelper::HasWebScheme(origin)) { 166 pending_database_info_.insert(PendingDatabaseInfo( 167 origin, name, description)); 168 } 169 } 170 171 void CannedBrowsingDataDatabaseHelper::Reset() { 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 173 pending_database_info_.clear(); 174 } 175 176 bool CannedBrowsingDataDatabaseHelper::empty() const { 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 178 return pending_database_info_.empty(); 179 } 180 181 size_t CannedBrowsingDataDatabaseHelper::GetDatabaseCount() const { 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 183 return pending_database_info_.size(); 184 } 185 186 const std::set<CannedBrowsingDataDatabaseHelper::PendingDatabaseInfo>& 187 CannedBrowsingDataDatabaseHelper::GetPendingDatabaseInfo() { 188 return pending_database_info_; 189 } 190 191 void CannedBrowsingDataDatabaseHelper::StartFetching( 192 const base::Callback<void(const std::list<DatabaseInfo>&)>& callback) { 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 194 DCHECK(!is_fetching_); 195 DCHECK_EQ(false, callback.is_null()); 196 197 is_fetching_ = true; 198 completion_callback_ = callback; 199 200 database_info_.clear(); 201 for (std::set<PendingDatabaseInfo>::const_iterator 202 info = pending_database_info_.begin(); 203 info != pending_database_info_.end(); ++info) { 204 DatabaseIdentifier identifier = 205 DatabaseIdentifier::CreateFromOrigin(info->origin); 206 207 database_info_.push_back(DatabaseInfo( 208 identifier, 209 info->name, 210 info->description, 211 0, 212 base::Time())); 213 } 214 215 BrowserThread::PostTask( 216 BrowserThread::UI, FROM_HERE, 217 base::Bind(&CannedBrowsingDataDatabaseHelper::NotifyInUIThread, this)); 218 } 219 220 CannedBrowsingDataDatabaseHelper::~CannedBrowsingDataDatabaseHelper() {} 221