blob: e749be32f8b28094de2c7a76f3e00587b5e9c1d7 [file] [log] [blame]
[email protected]0c7a6b2d2011-02-10 15:27:551// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]2823fb242010-09-23 08:53:262// 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_indexed_db_helper.h"
6
[email protected]006284f02011-10-19 22:06:237#include "base/bind.h"
[email protected]517717b2011-10-25 23:44:498#include "base/callback.h"
9#include "base/compiler_specific.h"
[email protected]2823fb242010-09-23 08:53:2610#include "base/file_util.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/scoped_ptr.h"
[email protected]2823fb242010-09-23 08:53:2612#include "base/message_loop.h"
[email protected]2823fb242010-09-23 08:53:2613#include "base/string_util.h"
14#include "base/utf_string_conversions.h"
[email protected]8ecad5e2010-12-02 21:18:3315#include "chrome/browser/profiles/profile.h"
[email protected]567812d2011-02-24 17:40:5016#include "content/browser/in_process_webkit/webkit_context.h"
[email protected]c38831a12011-10-28 12:44:4917#include "content/public/browser/browser_thread.h"
[email protected]ab308092011-08-25 23:37:1918#include "webkit/database/database_util.h"
[email protected]2823fb242010-09-23 08:53:2619#include "webkit/glue/webkit_glue.h"
20
[email protected]631bb742011-11-02 11:29:3921using content::BrowserThread;
[email protected]ab308092011-08-25 23:37:1922using webkit_database::DatabaseUtil;
[email protected]2823fb242010-09-23 08:53:2623
24namespace {
25
26class BrowsingDataIndexedDBHelperImpl : public BrowsingDataIndexedDBHelper {
27 public:
28 explicit BrowsingDataIndexedDBHelperImpl(Profile* profile);
29
30 virtual void StartFetching(
[email protected]517717b2011-10-25 23:44:4931 const base::Callback<void(const std::list<IndexedDBInfo>&)>&
32 callback) OVERRIDE;
33 virtual void CancelNotification() OVERRIDE;
34 virtual void DeleteIndexedDB(const GURL& origin) OVERRIDE;
[email protected]2823fb242010-09-23 08:53:2635
36 private:
37 virtual ~BrowsingDataIndexedDBHelperImpl();
38
39 // Enumerates all indexed database files in the WEBKIT thread.
40 void FetchIndexedDBInfoInWebKitThread();
41 // Notifies the completion callback in the UI thread.
42 void NotifyInUIThread();
[email protected]ab308092011-08-25 23:37:1943 // Delete a single indexed database in the WEBKIT thread.
44 void DeleteIndexedDBInWebKitThread(const GURL& origin);
[email protected]2823fb242010-09-23 08:53:2645
[email protected]ab308092011-08-25 23:37:1946 scoped_refptr<IndexedDBContext> indexed_db_context_;
[email protected]2823fb242010-09-23 08:53:2647
48 // This only mutates in the WEBKIT thread.
[email protected]713be8b2011-08-18 00:12:3049 std::list<IndexedDBInfo> indexed_db_info_;
[email protected]2823fb242010-09-23 08:53:2650
51 // This only mutates on the UI thread.
[email protected]517717b2011-10-25 23:44:4952 base::Callback<void(const std::list<IndexedDBInfo>&)> completion_callback_;
53
[email protected]2823fb242010-09-23 08:53:2654 // Indicates whether or not we're currently fetching information:
55 // it's true when StartFetching() is called in the UI thread, and it's reset
56 // after we notified the callback in the UI thread.
57 // This only mutates on the UI thread.
58 bool is_fetching_;
59
60 DISALLOW_COPY_AND_ASSIGN(BrowsingDataIndexedDBHelperImpl);
61};
62
63BrowsingDataIndexedDBHelperImpl::BrowsingDataIndexedDBHelperImpl(
64 Profile* profile)
[email protected]ab308092011-08-25 23:37:1965 : indexed_db_context_(profile->GetWebKitContext()->indexed_db_context()),
[email protected]2823fb242010-09-23 08:53:2666 is_fetching_(false) {
[email protected]ab308092011-08-25 23:37:1967 DCHECK(indexed_db_context_.get());
[email protected]2823fb242010-09-23 08:53:2668}
69
70BrowsingDataIndexedDBHelperImpl::~BrowsingDataIndexedDBHelperImpl() {
71}
72
73void BrowsingDataIndexedDBHelperImpl::StartFetching(
[email protected]517717b2011-10-25 23:44:4974 const base::Callback<void(const std::list<IndexedDBInfo>&)>& callback) {
[email protected]d04e7662010-10-10 22:24:4875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]2823fb242010-09-23 08:53:2676 DCHECK(!is_fetching_);
[email protected]517717b2011-10-25 23:44:4977 DCHECK_EQ(false, callback.is_null());
78
[email protected]2823fb242010-09-23 08:53:2679 is_fetching_ = true;
[email protected]517717b2011-10-25 23:44:4980 completion_callback_ = callback;
[email protected]d04e7662010-10-10 22:24:4881 BrowserThread::PostTask(
[email protected]e1dd5622011-12-20 12:28:5882 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
[email protected]006284f02011-10-19 22:06:2383 base::Bind(
84 &BrowsingDataIndexedDBHelperImpl::FetchIndexedDBInfoInWebKitThread,
85 this));
[email protected]2823fb242010-09-23 08:53:2686}
87
88void BrowsingDataIndexedDBHelperImpl::CancelNotification() {
[email protected]d04e7662010-10-10 22:24:4889 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]517717b2011-10-25 23:44:4990 completion_callback_.Reset();
[email protected]2823fb242010-09-23 08:53:2691}
92
[email protected]ab308092011-08-25 23:37:1993void BrowsingDataIndexedDBHelperImpl::DeleteIndexedDB(
94 const GURL& origin) {
[email protected]d04e7662010-10-10 22:24:4895 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 BrowserThread::PostTask(
[email protected]e1dd5622011-12-20 12:28:5897 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
[email protected]006284f02011-10-19 22:06:2398 base::Bind(
99 &BrowsingDataIndexedDBHelperImpl::DeleteIndexedDBInWebKitThread, this,
100 origin));
[email protected]2823fb242010-09-23 08:53:26101}
102
103void BrowsingDataIndexedDBHelperImpl::FetchIndexedDBInfoInWebKitThread() {
[email protected]e1dd5622011-12-20 12:28:58104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
[email protected]ab308092011-08-25 23:37:19105 std::vector<GURL> origins;
106 indexed_db_context_->GetAllOrigins(&origins);
107 for (std::vector<GURL>::const_iterator iter = origins.begin();
108 iter != origins.end(); ++iter) {
109 const GURL& origin = *iter;
110 if (origin.SchemeIs(chrome::kExtensionScheme))
111 continue; // Extension state is not considered browsing data.
112 indexed_db_info_.push_back(IndexedDBInfo(
113 origin,
114 indexed_db_context_->GetOriginDiskUsage(origin),
115 indexed_db_context_->GetOriginLastModified(origin)));
[email protected]2823fb242010-09-23 08:53:26116 }
117
[email protected]d04e7662010-10-10 22:24:48118 BrowserThread::PostTask(
119 BrowserThread::UI, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23120 base::Bind(&BrowsingDataIndexedDBHelperImpl::NotifyInUIThread, this));
[email protected]2823fb242010-09-23 08:53:26121}
122
123void BrowsingDataIndexedDBHelperImpl::NotifyInUIThread() {
[email protected]d04e7662010-10-10 22:24:48124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]2823fb242010-09-23 08:53:26125 DCHECK(is_fetching_);
126 // Note: completion_callback_ mutates only in the UI thread, so it's safe to
127 // test it here.
[email protected]517717b2011-10-25 23:44:49128 if (!completion_callback_.is_null()) {
129 completion_callback_.Run(indexed_db_info_);
130 completion_callback_.Reset();
[email protected]2823fb242010-09-23 08:53:26131 }
132 is_fetching_ = false;
133}
134
[email protected]ab308092011-08-25 23:37:19135void BrowsingDataIndexedDBHelperImpl::DeleteIndexedDBInWebKitThread(
136 const GURL& origin) {
[email protected]e1dd5622011-12-20 12:28:58137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
[email protected]ab308092011-08-25 23:37:19138 indexed_db_context_->DeleteIndexedDBForOrigin(origin);
[email protected]2823fb242010-09-23 08:53:26139}
140
141} // namespace
142
[email protected]d2f05d02011-01-27 18:51:01143BrowsingDataIndexedDBHelper::IndexedDBInfo::IndexedDBInfo(
[email protected]ab308092011-08-25 23:37:19144 const GURL& origin,
[email protected]d2f05d02011-01-27 18:51:01145 int64 size,
146 base::Time last_modified)
[email protected]ab308092011-08-25 23:37:19147 : origin(origin),
[email protected]d2f05d02011-01-27 18:51:01148 size(size),
149 last_modified(last_modified) {
150}
151
152BrowsingDataIndexedDBHelper::IndexedDBInfo::~IndexedDBInfo() {}
153
[email protected]2823fb242010-09-23 08:53:26154// static
155BrowsingDataIndexedDBHelper* BrowsingDataIndexedDBHelper::Create(
156 Profile* profile) {
157 return new BrowsingDataIndexedDBHelperImpl(profile);
158}
159
[email protected]0c7a6b2d2011-02-10 15:27:55160CannedBrowsingDataIndexedDBHelper::
161PendingIndexedDBInfo::PendingIndexedDBInfo() {
162}
163
164CannedBrowsingDataIndexedDBHelper::
165PendingIndexedDBInfo::PendingIndexedDBInfo(const GURL& origin,
166 const string16& description)
167 : origin(origin),
168 description(description) {
169}
170
171CannedBrowsingDataIndexedDBHelper::
172PendingIndexedDBInfo::~PendingIndexedDBInfo() {
173}
174
[email protected]ab308092011-08-25 23:37:19175CannedBrowsingDataIndexedDBHelper::CannedBrowsingDataIndexedDBHelper()
[email protected]517717b2011-10-25 23:44:49176 : is_fetching_(false) {
[email protected]2823fb242010-09-23 08:53:26177}
178
[email protected]712a9a02011-03-15 12:27:37179CannedBrowsingDataIndexedDBHelper* CannedBrowsingDataIndexedDBHelper::Clone() {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
181 CannedBrowsingDataIndexedDBHelper* clone =
[email protected]ab308092011-08-25 23:37:19182 new CannedBrowsingDataIndexedDBHelper();
[email protected]712a9a02011-03-15 12:27:37183
184 base::AutoLock auto_lock(lock_);
185 clone->pending_indexed_db_info_ = pending_indexed_db_info_;
186 clone->indexed_db_info_ = indexed_db_info_;
187 return clone;
188}
189
[email protected]2823fb242010-09-23 08:53:26190void CannedBrowsingDataIndexedDBHelper::AddIndexedDB(
[email protected]5000ade62010-11-08 23:20:49191 const GURL& origin, const string16& description) {
[email protected]0c7a6b2d2011-02-10 15:27:55192 base::AutoLock auto_lock(lock_);
193 pending_indexed_db_info_.push_back(PendingIndexedDBInfo(origin, description));
[email protected]2823fb242010-09-23 08:53:26194}
195
196void CannedBrowsingDataIndexedDBHelper::Reset() {
[email protected]0c7a6b2d2011-02-10 15:27:55197 base::AutoLock auto_lock(lock_);
[email protected]2823fb242010-09-23 08:53:26198 indexed_db_info_.clear();
[email protected]0c7a6b2d2011-02-10 15:27:55199 pending_indexed_db_info_.clear();
[email protected]2823fb242010-09-23 08:53:26200}
201
202bool CannedBrowsingDataIndexedDBHelper::empty() const {
[email protected]0c7a6b2d2011-02-10 15:27:55203 base::AutoLock auto_lock(lock_);
204 return indexed_db_info_.empty() && pending_indexed_db_info_.empty();
[email protected]2823fb242010-09-23 08:53:26205}
206
207void CannedBrowsingDataIndexedDBHelper::StartFetching(
[email protected]517717b2011-10-25 23:44:49208 const base::Callback<void(const std::list<IndexedDBInfo>&)>& callback) {
[email protected]0c7a6b2d2011-02-10 15:27:55209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
210 DCHECK(!is_fetching_);
[email protected]517717b2011-10-25 23:44:49211 DCHECK_EQ(false, callback.is_null());
212
[email protected]0c7a6b2d2011-02-10 15:27:55213 is_fetching_ = true;
[email protected]517717b2011-10-25 23:44:49214 completion_callback_ = callback;
[email protected]006284f02011-10-19 22:06:23215 BrowserThread::PostTask(
[email protected]e1dd5622011-12-20 12:28:58216 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23217 base::Bind(
218 &CannedBrowsingDataIndexedDBHelper::ConvertPendingInfoInWebKitThread,
219 this));
[email protected]2823fb242010-09-23 08:53:26220}
[email protected]8e383412010-10-19 16:57:03221
222CannedBrowsingDataIndexedDBHelper::~CannedBrowsingDataIndexedDBHelper() {}
[email protected]0c7a6b2d2011-02-10 15:27:55223
224void CannedBrowsingDataIndexedDBHelper::ConvertPendingInfoInWebKitThread() {
225 base::AutoLock auto_lock(lock_);
[email protected]713be8b2011-08-18 00:12:30226 for (std::list<PendingIndexedDBInfo>::const_iterator
[email protected]0c7a6b2d2011-02-10 15:27:55227 info = pending_indexed_db_info_.begin();
228 info != pending_indexed_db_info_.end(); ++info) {
[email protected]0c7a6b2d2011-02-10 15:27:55229 bool duplicate = false;
[email protected]713be8b2011-08-18 00:12:30230 for (std::list<IndexedDBInfo>::iterator
[email protected]0c7a6b2d2011-02-10 15:27:55231 indexed_db = indexed_db_info_.begin();
232 indexed_db != indexed_db_info_.end(); ++indexed_db) {
[email protected]ab308092011-08-25 23:37:19233 if (indexed_db->origin == info->origin) {
[email protected]0c7a6b2d2011-02-10 15:27:55234 duplicate = true;
235 break;
236 }
237 }
238 if (duplicate)
239 continue;
240
241 indexed_db_info_.push_back(IndexedDBInfo(
[email protected]ab308092011-08-25 23:37:19242 info->origin,
[email protected]0c7a6b2d2011-02-10 15:27:55243 0,
244 base::Time()));
245 }
246 pending_indexed_db_info_.clear();
247
248 BrowserThread::PostTask(
249 BrowserThread::UI, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23250 base::Bind(&CannedBrowsingDataIndexedDBHelper::NotifyInUIThread, this));
[email protected]0c7a6b2d2011-02-10 15:27:55251}
252
253void CannedBrowsingDataIndexedDBHelper::NotifyInUIThread() {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
255 DCHECK(is_fetching_);
[email protected]517717b2011-10-25 23:44:49256
257 // Completion_callback_ mutates only in the UI thread, so it's safe to test it
258 // here.
259 if (!completion_callback_.is_null()) {
260 completion_callback_.Run(indexed_db_info_);
261 completion_callback_.Reset();
[email protected]0c7a6b2d2011-02-10 15:27:55262 }
263 is_fetching_ = false;
264}
[email protected]45267a92011-05-31 13:28:01265
266void CannedBrowsingDataIndexedDBHelper::CancelNotification() {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]517717b2011-10-25 23:44:49268 completion_callback_.Reset();
[email protected]45267a92011-05-31 13:28:01269}