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