blob: 8b07235d445eb6ac712c13f93c0b1ecb32cf0882 [file] [log] [blame]
[email protected]2823fb242010-09-23 08:53:261// 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_indexed_db_helper.h"
6
7#include "base/file_util.h"
8#include "base/message_loop.h"
9#include "base/scoped_ptr.h"
10#include "base/string_util.h"
11#include "base/utf_string_conversions.h"
[email protected]ed7e6dd2010-10-12 02:02:4512#include "chrome/browser/browser_thread.h"
[email protected]2823fb242010-09-23 08:53:2613#include "chrome/browser/in_process_webkit/webkit_context.h"
[email protected]8ecad5e2010-12-02 21:18:3314#include "chrome/browser/profiles/profile.h"
[email protected]2823fb242010-09-23 08:53:2615#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
16#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
17#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
18#include "webkit/glue/webkit_glue.h"
19
20using WebKit::WebSecurityOrigin;
21
22namespace {
23
24class BrowsingDataIndexedDBHelperImpl : public BrowsingDataIndexedDBHelper {
25 public:
26 explicit BrowsingDataIndexedDBHelperImpl(Profile* profile);
27
28 virtual void StartFetching(
29 Callback1<const std::vector<IndexedDBInfo>& >::Type* callback);
30 virtual void CancelNotification();
31 virtual void DeleteIndexedDBFile(const FilePath& file_path);
32
33 private:
34 virtual ~BrowsingDataIndexedDBHelperImpl();
35
36 // Enumerates all indexed database files in the WEBKIT thread.
37 void FetchIndexedDBInfoInWebKitThread();
38 // Notifies the completion callback in the UI thread.
39 void NotifyInUIThread();
40 // Delete a single indexed database file in the WEBKIT thread.
41 void DeleteIndexedDBFileInWebKitThread(const FilePath& file_path);
42
43 Profile* profile_;
44
45 // This only mutates in the WEBKIT thread.
46 std::vector<IndexedDBInfo> indexed_db_info_;
47
48 // This only mutates on the UI thread.
49 scoped_ptr<Callback1<const std::vector<IndexedDBInfo>& >::Type >
50 completion_callback_;
51 // Indicates whether or not we're currently fetching information:
52 // it's true when StartFetching() is called in the UI thread, and it's reset
53 // after we notified the callback in the UI thread.
54 // This only mutates on the UI thread.
55 bool is_fetching_;
56
57 DISALLOW_COPY_AND_ASSIGN(BrowsingDataIndexedDBHelperImpl);
58};
59
60BrowsingDataIndexedDBHelperImpl::BrowsingDataIndexedDBHelperImpl(
61 Profile* profile)
62 : profile_(profile),
63 completion_callback_(NULL),
64 is_fetching_(false) {
65 DCHECK(profile_);
66}
67
68BrowsingDataIndexedDBHelperImpl::~BrowsingDataIndexedDBHelperImpl() {
69}
70
71void BrowsingDataIndexedDBHelperImpl::StartFetching(
72 Callback1<const std::vector<IndexedDBInfo>& >::Type* callback) {
[email protected]d04e7662010-10-10 22:24:4873 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]2823fb242010-09-23 08:53:2674 DCHECK(!is_fetching_);
75 DCHECK(callback);
76 is_fetching_ = true;
77 completion_callback_.reset(callback);
[email protected]d04e7662010-10-10 22:24:4878 BrowserThread::PostTask(
79 BrowserThread::WEBKIT, FROM_HERE,
[email protected]2823fb242010-09-23 08:53:2680 NewRunnableMethod(
81 this,
82 &BrowsingDataIndexedDBHelperImpl::FetchIndexedDBInfoInWebKitThread));
83}
84
85void BrowsingDataIndexedDBHelperImpl::CancelNotification() {
[email protected]d04e7662010-10-10 22:24:4886 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]2823fb242010-09-23 08:53:2687 completion_callback_.reset(NULL);
88}
89
90void BrowsingDataIndexedDBHelperImpl::DeleteIndexedDBFile(
91 const FilePath& file_path) {
[email protected]d04e7662010-10-10 22:24:4892 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93 BrowserThread::PostTask(
94 BrowserThread::WEBKIT, FROM_HERE,
[email protected]2823fb242010-09-23 08:53:2695 NewRunnableMethod(
96 this,
97 &BrowsingDataIndexedDBHelperImpl::
98 DeleteIndexedDBFileInWebKitThread,
99 file_path));
100}
101
102void BrowsingDataIndexedDBHelperImpl::FetchIndexedDBInfoInWebKitThread() {
[email protected]d04e7662010-10-10 22:24:48103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
[email protected]2823fb242010-09-23 08:53:26104 file_util::FileEnumerator file_enumerator(
105 profile_->GetWebKitContext()->data_path().Append(
106 IndexedDBContext::kIndexedDBDirectory),
107 false, file_util::FileEnumerator::FILES);
108 for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
109 file_path = file_enumerator.Next()) {
110 if (file_path.Extension() == IndexedDBContext::kIndexedDBExtension) {
[email protected]5000ade62010-11-08 23:20:49111 WebSecurityOrigin web_security_origin =
112 WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
113 webkit_glue::FilePathToWebString(file_path.BaseName()));
[email protected]2823fb242010-09-23 08:53:26114 if (EqualsASCII(web_security_origin.protocol(),
115 chrome::kExtensionScheme)) {
116 // Extension state is not considered browsing data.
117 continue;
118 }
119 base::PlatformFileInfo file_info;
120 bool ret = file_util::GetFileInfo(file_path, &file_info);
121 if (ret) {
122 indexed_db_info_.push_back(IndexedDBInfo(
123 web_security_origin.protocol().utf8(),
124 web_security_origin.host().utf8(),
125 web_security_origin.port(),
126 web_security_origin.databaseIdentifier().utf8(),
127 web_security_origin.toString().utf8(),
[email protected]2823fb242010-09-23 08:53:26128 file_path,
129 file_info.size,
130 file_info.last_modified));
131 }
132 }
133 }
134
[email protected]d04e7662010-10-10 22:24:48135 BrowserThread::PostTask(
136 BrowserThread::UI, FROM_HERE,
[email protected]2823fb242010-09-23 08:53:26137 NewRunnableMethod(
138 this, &BrowsingDataIndexedDBHelperImpl::NotifyInUIThread));
139}
140
141void BrowsingDataIndexedDBHelperImpl::NotifyInUIThread() {
[email protected]d04e7662010-10-10 22:24:48142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]2823fb242010-09-23 08:53:26143 DCHECK(is_fetching_);
144 // Note: completion_callback_ mutates only in the UI thread, so it's safe to
145 // test it here.
146 if (completion_callback_ != NULL) {
147 completion_callback_->Run(indexed_db_info_);
148 completion_callback_.reset();
149 }
150 is_fetching_ = false;
151}
152
153void BrowsingDataIndexedDBHelperImpl::DeleteIndexedDBFileInWebKitThread(
154 const FilePath& file_path) {
[email protected]d04e7662010-10-10 22:24:48155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
[email protected]2823fb242010-09-23 08:53:26156 // TODO(jochen): implement this once it's possible to delete indexed DBs.
157}
158
159} // namespace
160
161// static
162BrowsingDataIndexedDBHelper* BrowsingDataIndexedDBHelper::Create(
163 Profile* profile) {
164 return new BrowsingDataIndexedDBHelperImpl(profile);
165}
166
167CannedBrowsingDataIndexedDBHelper::CannedBrowsingDataIndexedDBHelper(
168 Profile* profile)
169 : profile_(profile) {
170 DCHECK(profile);
171}
172
173void CannedBrowsingDataIndexedDBHelper::AddIndexedDB(
[email protected]5000ade62010-11-08 23:20:49174 const GURL& origin, const string16& description) {
[email protected]2823fb242010-09-23 08:53:26175 WebSecurityOrigin web_security_origin =
176 WebSecurityOrigin::createFromString(
177 UTF8ToUTF16(origin.spec()));
178 std::string security_origin(web_security_origin.toString().utf8());
179
180 for (std::vector<IndexedDBInfo>::iterator
181 indexed_db = indexed_db_info_.begin();
182 indexed_db != indexed_db_info_.end(); ++indexed_db) {
183 if (indexed_db->origin == security_origin)
184 return;
185 }
186
187 indexed_db_info_.push_back(IndexedDBInfo(
188 web_security_origin.protocol().utf8(),
189 web_security_origin.host().utf8(),
190 web_security_origin.port(),
191 web_security_origin.databaseIdentifier().utf8(),
192 security_origin,
[email protected]2823fb242010-09-23 08:53:26193 profile_->GetWebKitContext()->indexed_db_context()->
[email protected]5000ade62010-11-08 23:20:49194 GetIndexedDBFilePath(web_security_origin.databaseIdentifier()),
[email protected]2823fb242010-09-23 08:53:26195 0,
196 base::Time()));
197}
198
199void CannedBrowsingDataIndexedDBHelper::Reset() {
200 indexed_db_info_.clear();
201}
202
203bool CannedBrowsingDataIndexedDBHelper::empty() const {
204 return indexed_db_info_.empty();
205}
206
207void CannedBrowsingDataIndexedDBHelper::StartFetching(
208 Callback1<const std::vector<IndexedDBInfo>& >::Type* callback) {
209 callback->Run(indexed_db_info_);
210 delete callback;
211}
[email protected]8e383412010-10-19 16:57:03212
213CannedBrowsingDataIndexedDBHelper::~CannedBrowsingDataIndexedDBHelper() {}