[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 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 | |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 7 | #include "base/bind.h" |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 8 | #include "base/callback.h" |
| 9 | #include "base/compiler_specific.h" |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 10 | #include "base/file_util.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 11 | #include "base/memory/scoped_ptr.h" |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 12 | #include "base/message_loop.h" |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 13 | #include "base/string_util.h" |
| 14 | #include "base/utf_string_conversions.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 15 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 567812d | 2011-02-24 17:40:50 | [diff] [blame] | 16 | #include "content/browser/in_process_webkit/webkit_context.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 17 | #include "content/public/browser/browser_thread.h" |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 18 | #include "webkit/database/database_util.h" |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 19 | #include "webkit/glue/webkit_glue.h" |
| 20 | |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 21 | using content::BrowserThread; |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 22 | using webkit_database::DatabaseUtil; |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 23 | |
| 24 | namespace { |
| 25 | |
| 26 | class BrowsingDataIndexedDBHelperImpl : public BrowsingDataIndexedDBHelper { |
| 27 | public: |
| 28 | explicit BrowsingDataIndexedDBHelperImpl(Profile* profile); |
| 29 | |
| 30 | virtual void StartFetching( |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 31 | 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] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 35 | |
| 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] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 43 | // Delete a single indexed database in the WEBKIT thread. |
| 44 | void DeleteIndexedDBInWebKitThread(const GURL& origin); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 45 | |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 46 | scoped_refptr<IndexedDBContext> indexed_db_context_; |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 47 | |
| 48 | // This only mutates in the WEBKIT thread. |
[email protected] | 713be8b | 2011-08-18 00:12:30 | [diff] [blame] | 49 | std::list<IndexedDBInfo> indexed_db_info_; |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 50 | |
| 51 | // This only mutates on the UI thread. |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 52 | base::Callback<void(const std::list<IndexedDBInfo>&)> completion_callback_; |
| 53 | |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 54 | // 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 | |
| 63 | BrowsingDataIndexedDBHelperImpl::BrowsingDataIndexedDBHelperImpl( |
| 64 | Profile* profile) |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 65 | : indexed_db_context_(profile->GetWebKitContext()->indexed_db_context()), |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 66 | is_fetching_(false) { |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 67 | DCHECK(indexed_db_context_.get()); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | BrowsingDataIndexedDBHelperImpl::~BrowsingDataIndexedDBHelperImpl() { |
| 71 | } |
| 72 | |
| 73 | void BrowsingDataIndexedDBHelperImpl::StartFetching( |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 74 | const base::Callback<void(const std::list<IndexedDBInfo>&)>& callback) { |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 75 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 76 | DCHECK(!is_fetching_); |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 77 | DCHECK_EQ(false, callback.is_null()); |
| 78 | |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 79 | is_fetching_ = true; |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 80 | completion_callback_ = callback; |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 81 | BrowserThread::PostTask( |
[email protected] | e1dd562 | 2011-12-20 12:28:58 | [diff] [blame] | 82 | BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 83 | base::Bind( |
| 84 | &BrowsingDataIndexedDBHelperImpl::FetchIndexedDBInfoInWebKitThread, |
| 85 | this)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | void BrowsingDataIndexedDBHelperImpl::CancelNotification() { |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 89 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 90 | completion_callback_.Reset(); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 91 | } |
| 92 | |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 93 | void BrowsingDataIndexedDBHelperImpl::DeleteIndexedDB( |
| 94 | const GURL& origin) { |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 95 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 96 | BrowserThread::PostTask( |
[email protected] | e1dd562 | 2011-12-20 12:28:58 | [diff] [blame] | 97 | BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 98 | base::Bind( |
| 99 | &BrowsingDataIndexedDBHelperImpl::DeleteIndexedDBInWebKitThread, this, |
| 100 | origin)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | void BrowsingDataIndexedDBHelperImpl::FetchIndexedDBInfoInWebKitThread() { |
[email protected] | e1dd562 | 2011-12-20 12:28:58 | [diff] [blame] | 104 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 105 | 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] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 116 | } |
| 117 | |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 118 | BrowserThread::PostTask( |
| 119 | BrowserThread::UI, FROM_HERE, |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 120 | base::Bind(&BrowsingDataIndexedDBHelperImpl::NotifyInUIThread, this)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | void BrowsingDataIndexedDBHelperImpl::NotifyInUIThread() { |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 124 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 125 | DCHECK(is_fetching_); |
| 126 | // Note: completion_callback_ mutates only in the UI thread, so it's safe to |
| 127 | // test it here. |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 128 | if (!completion_callback_.is_null()) { |
| 129 | completion_callback_.Run(indexed_db_info_); |
| 130 | completion_callback_.Reset(); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 131 | } |
| 132 | is_fetching_ = false; |
| 133 | } |
| 134 | |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 135 | void BrowsingDataIndexedDBHelperImpl::DeleteIndexedDBInWebKitThread( |
| 136 | const GURL& origin) { |
[email protected] | e1dd562 | 2011-12-20 12:28:58 | [diff] [blame] | 137 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 138 | indexed_db_context_->DeleteIndexedDBForOrigin(origin); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 139 | } |
| 140 | |
| 141 | } // namespace |
| 142 | |
[email protected] | d2f05d0 | 2011-01-27 18:51:01 | [diff] [blame] | 143 | BrowsingDataIndexedDBHelper::IndexedDBInfo::IndexedDBInfo( |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 144 | const GURL& origin, |
[email protected] | d2f05d0 | 2011-01-27 18:51:01 | [diff] [blame] | 145 | int64 size, |
| 146 | base::Time last_modified) |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 147 | : origin(origin), |
[email protected] | d2f05d0 | 2011-01-27 18:51:01 | [diff] [blame] | 148 | size(size), |
| 149 | last_modified(last_modified) { |
| 150 | } |
| 151 | |
| 152 | BrowsingDataIndexedDBHelper::IndexedDBInfo::~IndexedDBInfo() {} |
| 153 | |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 154 | // static |
| 155 | BrowsingDataIndexedDBHelper* BrowsingDataIndexedDBHelper::Create( |
| 156 | Profile* profile) { |
| 157 | return new BrowsingDataIndexedDBHelperImpl(profile); |
| 158 | } |
| 159 | |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 160 | CannedBrowsingDataIndexedDBHelper:: |
| 161 | PendingIndexedDBInfo::PendingIndexedDBInfo() { |
| 162 | } |
| 163 | |
| 164 | CannedBrowsingDataIndexedDBHelper:: |
| 165 | PendingIndexedDBInfo::PendingIndexedDBInfo(const GURL& origin, |
| 166 | const string16& description) |
| 167 | : origin(origin), |
| 168 | description(description) { |
| 169 | } |
| 170 | |
| 171 | CannedBrowsingDataIndexedDBHelper:: |
| 172 | PendingIndexedDBInfo::~PendingIndexedDBInfo() { |
| 173 | } |
| 174 | |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 175 | CannedBrowsingDataIndexedDBHelper::CannedBrowsingDataIndexedDBHelper() |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 176 | : is_fetching_(false) { |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 177 | } |
| 178 | |
[email protected] | 712a9a0 | 2011-03-15 12:27:37 | [diff] [blame] | 179 | CannedBrowsingDataIndexedDBHelper* CannedBrowsingDataIndexedDBHelper::Clone() { |
| 180 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 181 | CannedBrowsingDataIndexedDBHelper* clone = |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 182 | new CannedBrowsingDataIndexedDBHelper(); |
[email protected] | 712a9a0 | 2011-03-15 12:27:37 | [diff] [blame] | 183 | |
| 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] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 190 | void CannedBrowsingDataIndexedDBHelper::AddIndexedDB( |
[email protected] | 5000ade6 | 2010-11-08 23:20:49 | [diff] [blame] | 191 | const GURL& origin, const string16& description) { |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 192 | base::AutoLock auto_lock(lock_); |
| 193 | pending_indexed_db_info_.push_back(PendingIndexedDBInfo(origin, description)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | void CannedBrowsingDataIndexedDBHelper::Reset() { |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 197 | base::AutoLock auto_lock(lock_); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 198 | indexed_db_info_.clear(); |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 199 | pending_indexed_db_info_.clear(); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 200 | } |
| 201 | |
| 202 | bool CannedBrowsingDataIndexedDBHelper::empty() const { |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 203 | base::AutoLock auto_lock(lock_); |
| 204 | return indexed_db_info_.empty() && pending_indexed_db_info_.empty(); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | void CannedBrowsingDataIndexedDBHelper::StartFetching( |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 208 | const base::Callback<void(const std::list<IndexedDBInfo>&)>& callback) { |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 209 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 210 | DCHECK(!is_fetching_); |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 211 | DCHECK_EQ(false, callback.is_null()); |
| 212 | |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 213 | is_fetching_ = true; |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 214 | completion_callback_ = callback; |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 215 | BrowserThread::PostTask( |
[email protected] | e1dd562 | 2011-12-20 12:28:58 | [diff] [blame] | 216 | BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 217 | base::Bind( |
| 218 | &CannedBrowsingDataIndexedDBHelper::ConvertPendingInfoInWebKitThread, |
| 219 | this)); |
[email protected] | 2823fb24 | 2010-09-23 08:53:26 | [diff] [blame] | 220 | } |
[email protected] | 8e38341 | 2010-10-19 16:57:03 | [diff] [blame] | 221 | |
| 222 | CannedBrowsingDataIndexedDBHelper::~CannedBrowsingDataIndexedDBHelper() {} |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 223 | |
| 224 | void CannedBrowsingDataIndexedDBHelper::ConvertPendingInfoInWebKitThread() { |
| 225 | base::AutoLock auto_lock(lock_); |
[email protected] | 713be8b | 2011-08-18 00:12:30 | [diff] [blame] | 226 | for (std::list<PendingIndexedDBInfo>::const_iterator |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 227 | info = pending_indexed_db_info_.begin(); |
| 228 | info != pending_indexed_db_info_.end(); ++info) { |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 229 | bool duplicate = false; |
[email protected] | 713be8b | 2011-08-18 00:12:30 | [diff] [blame] | 230 | for (std::list<IndexedDBInfo>::iterator |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 231 | indexed_db = indexed_db_info_.begin(); |
| 232 | indexed_db != indexed_db_info_.end(); ++indexed_db) { |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 233 | if (indexed_db->origin == info->origin) { |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 234 | duplicate = true; |
| 235 | break; |
| 236 | } |
| 237 | } |
| 238 | if (duplicate) |
| 239 | continue; |
| 240 | |
| 241 | indexed_db_info_.push_back(IndexedDBInfo( |
[email protected] | ab30809 | 2011-08-25 23:37:19 | [diff] [blame] | 242 | info->origin, |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 243 | 0, |
| 244 | base::Time())); |
| 245 | } |
| 246 | pending_indexed_db_info_.clear(); |
| 247 | |
| 248 | BrowserThread::PostTask( |
| 249 | BrowserThread::UI, FROM_HERE, |
[email protected] | 006284f0 | 2011-10-19 22:06:23 | [diff] [blame] | 250 | base::Bind(&CannedBrowsingDataIndexedDBHelper::NotifyInUIThread, this)); |
[email protected] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 251 | } |
| 252 | |
| 253 | void CannedBrowsingDataIndexedDBHelper::NotifyInUIThread() { |
| 254 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 255 | DCHECK(is_fetching_); |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 256 | |
| 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] | 0c7a6b2d | 2011-02-10 15:27:55 | [diff] [blame] | 262 | } |
| 263 | is_fetching_ = false; |
| 264 | } |
[email protected] | 45267a9 | 2011-05-31 13:28:01 | [diff] [blame] | 265 | |
| 266 | void CannedBrowsingDataIndexedDBHelper::CancelNotification() { |
| 267 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
[email protected] | 517717b | 2011-10-25 23:44:49 | [diff] [blame] | 268 | completion_callback_.Reset(); |
[email protected] | 45267a9 | 2011-05-31 13:28:01 | [diff] [blame] | 269 | } |