OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/database_message_filter.h" | 5 #include "content/browser/renderer_host/database_message_filter.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
11 #include "content/browser/user_metrics.h" | 11 #include "content/browser/user_metrics.h" |
12 #include "content/common/database_messages.h" | 12 #include "content/common/database_messages.h" |
13 #include "content/common/result_codes.h" | 13 #include "content/common/result_codes.h" |
14 #include "googleurl/src/gurl.h" | 14 #include "googleurl/src/gurl.h" |
15 #include "third_party/sqlite/sqlite3.h" | 15 #include "third_party/sqlite/sqlite3.h" |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
17 #include "webkit/database/database_util.h" | 17 #include "webkit/database/database_util.h" |
18 #include "webkit/database/vfs_backend.h" | 18 #include "webkit/database/vfs_backend.h" |
| 19 #include "webkit/quota/quota_manager.h" |
19 | 20 |
20 #if defined(OS_POSIX) | 21 #if defined(OS_POSIX) |
21 #include "base/file_descriptor_posix.h" | 22 #include "base/file_descriptor_posix.h" |
22 #endif | 23 #endif |
23 | 24 |
| 25 using quota::QuotaManager; |
| 26 using quota::QuotaManagerProxy; |
| 27 using quota::QuotaStatusCode; |
24 using WebKit::WebSecurityOrigin; | 28 using WebKit::WebSecurityOrigin; |
25 using webkit_database::DatabaseTracker; | 29 using webkit_database::DatabaseTracker; |
26 using webkit_database::DatabaseUtil; | 30 using webkit_database::DatabaseUtil; |
27 using webkit_database::VfsBackend; | 31 using webkit_database::VfsBackend; |
28 | 32 |
| 33 namespace { |
| 34 |
| 35 class MyGetUsageAndQuotaCallback |
| 36 : public QuotaManager::GetUsageAndQuotaCallback { |
| 37 public: |
| 38 MyGetUsageAndQuotaCallback( |
| 39 DatabaseMessageFilter* sender, IPC::Message* reply_msg) |
| 40 : sender_(sender), reply_msg_(reply_msg) {} |
| 41 |
| 42 virtual void RunWithParams( |
| 43 const Tuple3<QuotaStatusCode, int64, int64>& params) { |
| 44 Run(params.a, params.b, params.c); |
| 45 } |
| 46 |
| 47 void Run(QuotaStatusCode status, int64 usage, int64 quota) { |
| 48 int64 available = 0; |
| 49 if ((status == quota::kQuotaStatusOk) && (usage < quota)) |
| 50 available = quota - usage; |
| 51 DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams( |
| 52 reply_msg_.get(), available); |
| 53 sender_->Send(reply_msg_.release()); |
| 54 } |
| 55 |
| 56 private: |
| 57 scoped_refptr<DatabaseMessageFilter> sender_; |
| 58 scoped_ptr<IPC::Message> reply_msg_; |
| 59 }; |
| 60 |
29 const int kNumDeleteRetries = 2; | 61 const int kNumDeleteRetries = 2; |
30 const int kDelayDeleteRetryMs = 100; | 62 const int kDelayDeleteRetryMs = 100; |
31 | 63 |
| 64 } // namespace |
| 65 |
32 DatabaseMessageFilter::DatabaseMessageFilter( | 66 DatabaseMessageFilter::DatabaseMessageFilter( |
33 webkit_database::DatabaseTracker* db_tracker) | 67 webkit_database::DatabaseTracker* db_tracker) |
34 : db_tracker_(db_tracker), | 68 : db_tracker_(db_tracker), |
35 observer_added_(false) { | 69 observer_added_(false) { |
36 DCHECK(db_tracker_); | 70 DCHECK(db_tracker_); |
37 } | 71 } |
38 | 72 |
39 void DatabaseMessageFilter::OnChannelClosing() { | 73 void DatabaseMessageFilter::OnChannelClosing() { |
40 BrowserMessageFilter::OnChannelClosing(); | 74 BrowserMessageFilter::OnChannelClosing(); |
41 if (observer_added_) { | 75 if (observer_added_) { |
42 observer_added_ = false; | 76 observer_added_ = false; |
43 BrowserThread::PostTask( | 77 BrowserThread::PostTask( |
44 BrowserThread::FILE, FROM_HERE, | 78 BrowserThread::FILE, FROM_HERE, |
45 NewRunnableMethod(this, &DatabaseMessageFilter::RemoveObserver)); | 79 NewRunnableMethod(this, &DatabaseMessageFilter::RemoveObserver)); |
46 } | 80 } |
47 } | 81 } |
48 | 82 |
49 void DatabaseMessageFilter::AddObserver() { | 83 void DatabaseMessageFilter::AddObserver() { |
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
51 db_tracker_->AddObserver(this); | 85 db_tracker_->AddObserver(this); |
52 } | 86 } |
53 | 87 |
54 void DatabaseMessageFilter::RemoveObserver() { | 88 void DatabaseMessageFilter::RemoveObserver() { |
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 90 db_tracker_->RemoveObserver(this); |
56 | 91 |
57 // If the renderer process died without closing all databases, | 92 // If the renderer process died without closing all databases, |
58 // then we need to manually close those connections | 93 // then we need to manually close those connections |
59 db_tracker_->CloseDatabases(database_connections_); | 94 db_tracker_->CloseDatabases(database_connections_); |
60 database_connections_.RemoveAllConnections(); | 95 database_connections_.RemoveAllConnections(); |
61 | |
62 db_tracker_->RemoveObserver(this); | |
63 } | 96 } |
64 | 97 |
65 void DatabaseMessageFilter::OverrideThreadForMessage( | 98 void DatabaseMessageFilter::OverrideThreadForMessage( |
66 const IPC::Message& message, | 99 const IPC::Message& message, |
67 BrowserThread::ID* thread) { | 100 BrowserThread::ID* thread) { |
68 if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart) | 101 if (message.type() == DatabaseHostMsg_GetSpaceAvailable::ID) |
| 102 *thread = BrowserThread::IO; |
| 103 else if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart) |
69 *thread = BrowserThread::FILE; | 104 *thread = BrowserThread::FILE; |
70 | 105 |
71 if (message.type() == DatabaseHostMsg_OpenFile::ID && !observer_added_) { | 106 if (message.type() == DatabaseHostMsg_Opened::ID && !observer_added_) { |
72 observer_added_ = true; | 107 observer_added_ = true; |
73 BrowserThread::PostTask( | 108 BrowserThread::PostTask( |
74 BrowserThread::FILE, FROM_HERE, | 109 BrowserThread::FILE, FROM_HERE, |
75 NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver)); | 110 NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver)); |
76 } | 111 } |
77 } | 112 } |
78 | 113 |
79 bool DatabaseMessageFilter::OnMessageReceived( | 114 bool DatabaseMessageFilter::OnMessageReceived( |
80 const IPC::Message& message, | 115 const IPC::Message& message, |
81 bool* message_was_ok) { | 116 bool* message_was_ok) { |
82 bool handled = true; | 117 bool handled = true; |
83 IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok) | 118 IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok) |
84 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile, | 119 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile, |
85 OnDatabaseOpenFile) | 120 OnDatabaseOpenFile) |
86 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile, | 121 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile, |
87 OnDatabaseDeleteFile) | 122 OnDatabaseDeleteFile) |
88 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes, | 123 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes, |
89 OnDatabaseGetFileAttributes) | 124 OnDatabaseGetFileAttributes) |
90 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize, | 125 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize, |
91 OnDatabaseGetFileSize) | 126 OnDatabaseGetFileSize) |
| 127 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetSpaceAvailable, |
| 128 OnDatabaseGetSpaceAvailable) |
92 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened) | 129 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened) |
93 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified) | 130 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified) |
94 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed) | 131 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed) |
95 IPC_MESSAGE_UNHANDLED(handled = false) | 132 IPC_MESSAGE_UNHANDLED(handled = false) |
96 IPC_END_MESSAGE_MAP_EX() | 133 IPC_END_MESSAGE_MAP_EX() |
97 return handled; | 134 return handled; |
98 } | 135 } |
99 | 136 |
100 DatabaseMessageFilter::~DatabaseMessageFilter() { | 137 DatabaseMessageFilter::~DatabaseMessageFilter() { |
101 } | 138 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); | 250 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); |
214 if (!db_file.empty()) | 251 if (!db_file.empty()) |
215 attributes = VfsBackend::GetFileAttributes(db_file); | 252 attributes = VfsBackend::GetFileAttributes(db_file); |
216 | 253 |
217 DatabaseHostMsg_GetFileAttributes::WriteReplyParams( | 254 DatabaseHostMsg_GetFileAttributes::WriteReplyParams( |
218 reply_msg, attributes); | 255 reply_msg, attributes); |
219 Send(reply_msg); | 256 Send(reply_msg); |
220 } | 257 } |
221 | 258 |
222 void DatabaseMessageFilter::OnDatabaseGetFileSize( | 259 void DatabaseMessageFilter::OnDatabaseGetFileSize( |
223 const string16& vfs_file_name, IPC::Message* reply_msg) { | 260 const string16& vfs_file_name, IPC::Message* reply_msg) { |
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
225 int64 size = 0; | 262 int64 size = 0; |
226 FilePath db_file = | 263 FilePath db_file = |
227 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); | 264 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); |
228 if (!db_file.empty()) | 265 if (!db_file.empty()) |
229 size = VfsBackend::GetFileSize(db_file); | 266 size = VfsBackend::GetFileSize(db_file); |
230 | 267 |
231 DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size); | 268 DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size); |
232 Send(reply_msg); | 269 Send(reply_msg); |
233 } | 270 } |
234 | 271 |
| 272 void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable( |
| 273 const string16& origin_identifier, IPC::Message* reply_msg) { |
| 274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 275 DCHECK(db_tracker_->quota_manager_proxy()); |
| 276 |
| 277 QuotaManager* quota_manager = |
| 278 db_tracker_->quota_manager_proxy()->quota_manager(); |
| 279 if (!quota_manager) { |
| 280 NOTREACHED(); // The system is shutting down, messages are unexpected. |
| 281 DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams( |
| 282 reply_msg, static_cast<int64>(0)); |
| 283 Send(reply_msg); |
| 284 return; |
| 285 } |
| 286 |
| 287 quota_manager->GetUsageAndQuota( |
| 288 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), |
| 289 quota::kStorageTypeTemporary, |
| 290 new MyGetUsageAndQuotaCallback(this, reply_msg)); |
| 291 } |
| 292 |
235 void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier, | 293 void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier, |
236 const string16& database_name, | 294 const string16& database_name, |
237 const string16& description, | 295 const string16& description, |
238 int64 estimated_size) { | 296 int64 estimated_size) { |
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
240 int64 database_size = 0; | 298 int64 database_size = 0; |
241 int64 space_available = 0; | 299 int64 space_available_not_used = 0; |
| 300 db_tracker_->DatabaseOpened(origin_identifier, database_name, description, |
| 301 estimated_size, &database_size, |
| 302 &space_available_not_used); |
242 database_connections_.AddConnection(origin_identifier, database_name); | 303 database_connections_.AddConnection(origin_identifier, database_name); |
243 db_tracker_->DatabaseOpened(origin_identifier, database_name, description, | |
244 estimated_size, &database_size, &space_available); | |
245 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, | 304 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, |
246 database_size, space_available)); | 305 database_size)); |
247 } | 306 } |
248 | 307 |
249 void DatabaseMessageFilter::OnDatabaseModified( | 308 void DatabaseMessageFilter::OnDatabaseModified( |
250 const string16& origin_identifier, | 309 const string16& origin_identifier, |
251 const string16& database_name) { | 310 const string16& database_name) { |
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
253 if (!database_connections_.IsDatabaseOpened( | 312 if (!database_connections_.IsDatabaseOpened( |
254 origin_identifier, database_name)) { | 313 origin_identifier, database_name)) { |
255 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); | 314 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); |
256 BadMessageReceived(); | 315 BadMessageReceived(); |
257 return; | 316 return; |
258 } | 317 } |
259 | 318 |
260 db_tracker_->DatabaseModified(origin_identifier, database_name); | 319 db_tracker_->DatabaseModified(origin_identifier, database_name); |
261 } | 320 } |
262 | 321 |
263 void DatabaseMessageFilter::OnDatabaseClosed(const string16& origin_identifier, | 322 void DatabaseMessageFilter::OnDatabaseClosed(const string16& origin_identifier, |
264 const string16& database_name) { | 323 const string16& database_name) { |
265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
266 if (!database_connections_.IsDatabaseOpened( | 325 if (!database_connections_.IsDatabaseOpened( |
267 origin_identifier, database_name)) { | 326 origin_identifier, database_name)) { |
268 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); | 327 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); |
269 BadMessageReceived(); | 328 BadMessageReceived(); |
270 return; | 329 return; |
271 } | 330 } |
272 | 331 |
| 332 database_connections_.RemoveConnection(origin_identifier, database_name); |
273 db_tracker_->DatabaseClosed(origin_identifier, database_name); | 333 db_tracker_->DatabaseClosed(origin_identifier, database_name); |
274 database_connections_.RemoveConnection(origin_identifier, database_name); | |
275 } | 334 } |
276 | 335 |
277 void DatabaseMessageFilter::OnDatabaseSizeChanged( | 336 void DatabaseMessageFilter::OnDatabaseSizeChanged( |
278 const string16& origin_identifier, | 337 const string16& origin_identifier, |
279 const string16& database_name, | 338 const string16& database_name, |
280 int64 database_size, | 339 int64 database_size, |
281 int64 space_available) { | 340 int64 space_available_not_used) { |
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
283 if (database_connections_.IsOriginUsed(origin_identifier)) { | 342 if (database_connections_.IsOriginUsed(origin_identifier)) { |
284 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, | 343 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, |
285 database_size, space_available)); | 344 database_size)); |
286 } | 345 } |
287 } | 346 } |
288 | 347 |
289 void DatabaseMessageFilter::OnDatabaseScheduledForDeletion( | 348 void DatabaseMessageFilter::OnDatabaseScheduledForDeletion( |
290 const string16& origin_identifier, | 349 const string16& origin_identifier, |
291 const string16& database_name) { | 350 const string16& database_name) { |
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
293 Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name)); | 352 Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name)); |
294 } | 353 } |
OLD | NEW |