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 // Params are <status, usage, quota> | |
45 int64 available = 0; | |
46 if ((params.a == quota::kQuotaStatusOk) && (params.b < params.c)) | |
47 available = params.c - params.b; | |
48 DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams( | |
49 reply_msg_.get(), available); | |
50 sender_->Send(reply_msg_.release()); | |
51 } | |
52 | |
53 private: | |
54 scoped_refptr<DatabaseMessageFilter> sender_; | |
55 scoped_ptr<IPC::Message> reply_msg_; | |
michaeln
2011/05/22 21:49:02
MyGetUsageAndQuotaCallback can be deleted w/o havi
| |
56 }; | |
57 | |
29 const int kNumDeleteRetries = 2; | 58 const int kNumDeleteRetries = 2; |
30 const int kDelayDeleteRetryMs = 100; | 59 const int kDelayDeleteRetryMs = 100; |
31 | 60 |
61 } // namespace | |
62 | |
32 DatabaseMessageFilter::DatabaseMessageFilter( | 63 DatabaseMessageFilter::DatabaseMessageFilter( |
33 webkit_database::DatabaseTracker* db_tracker) | 64 webkit_database::DatabaseTracker* db_tracker) |
34 : db_tracker_(db_tracker), | 65 : db_tracker_(db_tracker), |
35 observer_added_(false) { | 66 observer_added_(false) { |
36 DCHECK(db_tracker_); | 67 DCHECK(db_tracker_); |
37 } | 68 } |
38 | 69 |
39 void DatabaseMessageFilter::OnChannelClosing() { | 70 void DatabaseMessageFilter::OnChannelClosing() { |
40 BrowserMessageFilter::OnChannelClosing(); | 71 BrowserMessageFilter::OnChannelClosing(); |
41 if (observer_added_) { | 72 if (observer_added_) { |
42 observer_added_ = false; | 73 observer_added_ = false; |
43 BrowserThread::PostTask( | 74 BrowserThread::PostTask( |
44 BrowserThread::FILE, FROM_HERE, | 75 BrowserThread::FILE, FROM_HERE, |
45 NewRunnableMethod(this, &DatabaseMessageFilter::RemoveObserver)); | 76 NewRunnableMethod(this, &DatabaseMessageFilter::RemoveObserver)); |
46 } | 77 } |
47 } | 78 } |
48 | 79 |
49 void DatabaseMessageFilter::AddObserver() { | 80 void DatabaseMessageFilter::AddObserver() { |
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
51 db_tracker_->AddObserver(this); | 82 db_tracker_->AddObserver(this); |
52 } | 83 } |
53 | 84 |
54 void DatabaseMessageFilter::RemoveObserver() { | 85 void DatabaseMessageFilter::RemoveObserver() { |
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
87 db_tracker_->RemoveObserver(this); | |
56 | 88 |
57 // If the renderer process died without closing all databases, | 89 // If the renderer process died without closing all databases, |
58 // then we need to manually close those connections | 90 // then we need to manually close those connections |
59 db_tracker_->CloseDatabases(database_connections_); | 91 db_tracker_->CloseDatabases(database_connections_); |
60 database_connections_.RemoveAllConnections(); | 92 database_connections_.RemoveAllConnections(); |
61 | |
62 db_tracker_->RemoveObserver(this); | |
63 } | 93 } |
64 | 94 |
65 void DatabaseMessageFilter::OverrideThreadForMessage( | 95 void DatabaseMessageFilter::OverrideThreadForMessage( |
66 const IPC::Message& message, | 96 const IPC::Message& message, |
67 BrowserThread::ID* thread) { | 97 BrowserThread::ID* thread) { |
68 if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart) | 98 if (message.type() == DatabaseHostMsg_GetSpaceAvailable::ID) |
99 *thread = BrowserThread::IO; | |
100 else if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart) | |
69 *thread = BrowserThread::FILE; | 101 *thread = BrowserThread::FILE; |
70 | 102 |
71 if (message.type() == DatabaseHostMsg_OpenFile::ID && !observer_added_) { | 103 if (message.type() == DatabaseHostMsg_Opened::ID && !observer_added_) { |
72 observer_added_ = true; | 104 observer_added_ = true; |
73 BrowserThread::PostTask( | 105 BrowserThread::PostTask( |
74 BrowserThread::FILE, FROM_HERE, | 106 BrowserThread::FILE, FROM_HERE, |
75 NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver)); | 107 NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver)); |
76 } | 108 } |
77 } | 109 } |
78 | 110 |
79 bool DatabaseMessageFilter::OnMessageReceived( | 111 bool DatabaseMessageFilter::OnMessageReceived( |
80 const IPC::Message& message, | 112 const IPC::Message& message, |
81 bool* message_was_ok) { | 113 bool* message_was_ok) { |
82 bool handled = true; | 114 bool handled = true; |
83 IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok) | 115 IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok) |
84 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile, | 116 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile, |
85 OnDatabaseOpenFile) | 117 OnDatabaseOpenFile) |
86 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile, | 118 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile, |
87 OnDatabaseDeleteFile) | 119 OnDatabaseDeleteFile) |
88 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes, | 120 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes, |
89 OnDatabaseGetFileAttributes) | 121 OnDatabaseGetFileAttributes) |
90 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize, | 122 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize, |
91 OnDatabaseGetFileSize) | 123 OnDatabaseGetFileSize) |
124 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetSpaceAvailable, | |
125 OnDatabaseGetSpaceAvailable) | |
92 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened) | 126 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened) |
93 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified) | 127 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified) |
94 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed) | 128 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed) |
95 IPC_MESSAGE_UNHANDLED(handled = false) | 129 IPC_MESSAGE_UNHANDLED(handled = false) |
96 IPC_END_MESSAGE_MAP_EX() | 130 IPC_END_MESSAGE_MAP_EX() |
97 return handled; | 131 return handled; |
98 } | 132 } |
99 | 133 |
100 DatabaseMessageFilter::~DatabaseMessageFilter() { | 134 DatabaseMessageFilter::~DatabaseMessageFilter() { |
101 } | 135 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); | 247 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); |
214 if (!db_file.empty()) | 248 if (!db_file.empty()) |
215 attributes = VfsBackend::GetFileAttributes(db_file); | 249 attributes = VfsBackend::GetFileAttributes(db_file); |
216 | 250 |
217 DatabaseHostMsg_GetFileAttributes::WriteReplyParams( | 251 DatabaseHostMsg_GetFileAttributes::WriteReplyParams( |
218 reply_msg, attributes); | 252 reply_msg, attributes); |
219 Send(reply_msg); | 253 Send(reply_msg); |
220 } | 254 } |
221 | 255 |
222 void DatabaseMessageFilter::OnDatabaseGetFileSize( | 256 void DatabaseMessageFilter::OnDatabaseGetFileSize( |
223 const string16& vfs_file_name, IPC::Message* reply_msg) { | 257 const string16& vfs_file_name, IPC::Message* reply_msg) { |
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
225 int64 size = 0; | 259 int64 size = 0; |
226 FilePath db_file = | 260 FilePath db_file = |
227 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); | 261 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); |
228 if (!db_file.empty()) | 262 if (!db_file.empty()) |
229 size = VfsBackend::GetFileSize(db_file); | 263 size = VfsBackend::GetFileSize(db_file); |
230 | 264 |
231 DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size); | 265 DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size); |
232 Send(reply_msg); | 266 Send(reply_msg); |
233 } | 267 } |
234 | 268 |
269 void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable( | |
270 const string16& origin_identifier, IPC::Message* reply_msg) { | |
271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
272 DCHECK(db_tracker_->quota_manager_proxy()); | |
273 | |
274 QuotaManager* quota_manager = | |
275 db_tracker_->quota_manager_proxy()->quota_manager(); | |
276 if (!quota_manager) { | |
277 NOTREACHED(); // The system is shutting down, messages are unexpected. | |
278 DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(reply_msg, 0LL); | |
279 Send(reply_msg); | |
280 return; | |
281 } | |
282 | |
283 quota_manager->GetUsageAndQuota( | |
284 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), | |
285 quota::kStorageTypeTemporary, | |
286 new MyGetUsageAndQuotaCallback(this, reply_msg)); | |
michaeln
2011/05/22 21:49:02
the callback is deleted by the QuotaMgr
| |
287 } | |
288 | |
235 void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier, | 289 void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier, |
236 const string16& database_name, | 290 const string16& database_name, |
237 const string16& description, | 291 const string16& description, |
238 int64 estimated_size) { | 292 int64 estimated_size) { |
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
240 int64 database_size = 0; | 294 int64 database_size = 0; |
241 int64 space_available = 0; | 295 int64 space_available_not_used = 0; |
296 db_tracker_->DatabaseOpened(origin_identifier, database_name, description, | |
297 estimated_size, &database_size, | |
298 &space_available_not_used); | |
242 database_connections_.AddConnection(origin_identifier, database_name); | 299 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, | 300 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, |
246 database_size, space_available)); | 301 database_size)); |
247 } | 302 } |
248 | 303 |
249 void DatabaseMessageFilter::OnDatabaseModified( | 304 void DatabaseMessageFilter::OnDatabaseModified( |
250 const string16& origin_identifier, | 305 const string16& origin_identifier, |
251 const string16& database_name) { | 306 const string16& database_name) { |
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
253 if (!database_connections_.IsDatabaseOpened( | 308 if (!database_connections_.IsDatabaseOpened( |
254 origin_identifier, database_name)) { | 309 origin_identifier, database_name)) { |
255 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); | 310 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); |
256 BadMessageReceived(); | 311 BadMessageReceived(); |
257 return; | 312 return; |
258 } | 313 } |
259 | 314 |
260 db_tracker_->DatabaseModified(origin_identifier, database_name); | 315 db_tracker_->DatabaseModified(origin_identifier, database_name); |
261 } | 316 } |
262 | 317 |
263 void DatabaseMessageFilter::OnDatabaseClosed(const string16& origin_identifier, | 318 void DatabaseMessageFilter::OnDatabaseClosed(const string16& origin_identifier, |
264 const string16& database_name) { | 319 const string16& database_name) { |
265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
266 if (!database_connections_.IsDatabaseOpened( | 321 if (!database_connections_.IsDatabaseOpened( |
267 origin_identifier, database_name)) { | 322 origin_identifier, database_name)) { |
268 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); | 323 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); |
269 BadMessageReceived(); | 324 BadMessageReceived(); |
270 return; | 325 return; |
271 } | 326 } |
272 | 327 |
328 database_connections_.RemoveConnection(origin_identifier, database_name); | |
273 db_tracker_->DatabaseClosed(origin_identifier, database_name); | 329 db_tracker_->DatabaseClosed(origin_identifier, database_name); |
274 database_connections_.RemoveConnection(origin_identifier, database_name); | |
275 } | 330 } |
276 | 331 |
277 void DatabaseMessageFilter::OnDatabaseSizeChanged( | 332 void DatabaseMessageFilter::OnDatabaseSizeChanged( |
278 const string16& origin_identifier, | 333 const string16& origin_identifier, |
279 const string16& database_name, | 334 const string16& database_name, |
280 int64 database_size, | 335 int64 database_size, |
281 int64 space_available) { | 336 int64 space_available_not_used) { |
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
283 if (database_connections_.IsOriginUsed(origin_identifier)) { | 338 if (database_connections_.IsOriginUsed(origin_identifier)) { |
284 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, | 339 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, |
285 database_size, space_available)); | 340 database_size)); |
286 } | 341 } |
287 } | 342 } |
288 | 343 |
289 void DatabaseMessageFilter::OnDatabaseScheduledForDeletion( | 344 void DatabaseMessageFilter::OnDatabaseScheduledForDeletion( |
290 const string16& origin_identifier, | 345 const string16& origin_identifier, |
291 const string16& database_name) { | 346 const string16& database_name) { |
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
293 Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name)); | 348 Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name)); |
294 } | 349 } |
OLD | NEW |