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