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* filter, IPC::Message* reply_msg) | |
40 : 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 filter_->Send(reply_msg_.release()); | |
51 } | |
52 | |
53 private: | |
54 scoped_refptr<DatabaseMessageFilter> filter_; | |
55 scoped_ptr<IPC::Message> reply_msg_; | |
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_) { |
(...skipping 16 matching lines...) Expand all Loading... | |
58 // then we need to manually close those connections | 89 // then we need to manually close those connections |
59 db_tracker_->CloseDatabases(database_connections_); | 90 db_tracker_->CloseDatabases(database_connections_); |
60 database_connections_.RemoveAllConnections(); | 91 database_connections_.RemoveAllConnections(); |
61 | 92 |
62 db_tracker_->RemoveObserver(this); | 93 db_tracker_->RemoveObserver(this); |
63 } | 94 } |
64 | 95 |
65 void DatabaseMessageFilter::OverrideThreadForMessage( | 96 void DatabaseMessageFilter::OverrideThreadForMessage( |
66 const IPC::Message& message, | 97 const IPC::Message& message, |
67 BrowserThread::ID* thread) { | 98 BrowserThread::ID* thread) { |
68 if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart) | 99 if (message.type() == DatabaseHostMsg_GetSpaceAvailable::ID) |
100 *thread = BrowserThread::IO; | |
101 else if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart) | |
69 *thread = BrowserThread::FILE; | 102 *thread = BrowserThread::FILE; |
70 | 103 |
71 if (message.type() == DatabaseHostMsg_OpenFile::ID && !observer_added_) { | 104 if (message.type() == DatabaseHostMsg_Opened::ID && !observer_added_) { |
72 observer_added_ = true; | 105 observer_added_ = true; |
73 BrowserThread::PostTask( | 106 BrowserThread::PostTask( |
74 BrowserThread::FILE, FROM_HERE, | 107 BrowserThread::FILE, FROM_HERE, |
75 NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver)); | 108 NewRunnableMethod(this, &DatabaseMessageFilter::AddObserver)); |
76 } | 109 } |
77 } | 110 } |
78 | 111 |
79 bool DatabaseMessageFilter::OnMessageReceived( | 112 bool DatabaseMessageFilter::OnMessageReceived( |
80 const IPC::Message& message, | 113 const IPC::Message& message, |
81 bool* message_was_ok) { | 114 bool* message_was_ok) { |
82 bool handled = true; | 115 bool handled = true; |
83 IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok) | 116 IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok) |
84 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile, | 117 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile, |
85 OnDatabaseOpenFile) | 118 OnDatabaseOpenFile) |
86 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile, | 119 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile, |
87 OnDatabaseDeleteFile) | 120 OnDatabaseDeleteFile) |
88 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes, | 121 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes, |
89 OnDatabaseGetFileAttributes) | 122 OnDatabaseGetFileAttributes) |
90 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize, | 123 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize, |
91 OnDatabaseGetFileSize) | 124 OnDatabaseGetFileSize) |
125 IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetSpaceAvailable, | |
126 OnDatabaseGetSpaceAvailable) | |
92 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened) | 127 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened) |
93 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified) | 128 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified) |
94 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed) | 129 IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed) |
95 IPC_MESSAGE_UNHANDLED(handled = false) | 130 IPC_MESSAGE_UNHANDLED(handled = false) |
96 IPC_END_MESSAGE_MAP_EX() | 131 IPC_END_MESSAGE_MAP_EX() |
97 return handled; | 132 return handled; |
98 } | 133 } |
99 | 134 |
100 DatabaseMessageFilter::~DatabaseMessageFilter() { | 135 DatabaseMessageFilter::~DatabaseMessageFilter() { |
101 } | 136 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); | 248 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); |
214 if (!db_file.empty()) | 249 if (!db_file.empty()) |
215 attributes = VfsBackend::GetFileAttributes(db_file); | 250 attributes = VfsBackend::GetFileAttributes(db_file); |
216 | 251 |
217 DatabaseHostMsg_GetFileAttributes::WriteReplyParams( | 252 DatabaseHostMsg_GetFileAttributes::WriteReplyParams( |
218 reply_msg, attributes); | 253 reply_msg, attributes); |
219 Send(reply_msg); | 254 Send(reply_msg); |
220 } | 255 } |
221 | 256 |
222 void DatabaseMessageFilter::OnDatabaseGetFileSize( | 257 void DatabaseMessageFilter::OnDatabaseGetFileSize( |
223 const string16& vfs_file_name, IPC::Message* reply_msg) { | 258 const string16& vfs_file_name, IPC::Message* reply_msg) { |
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
225 int64 size = 0; | 260 int64 size = 0; |
226 FilePath db_file = | 261 FilePath db_file = |
227 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); | 262 DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name); |
228 if (!db_file.empty()) | 263 if (!db_file.empty()) |
229 size = VfsBackend::GetFileSize(db_file); | 264 size = VfsBackend::GetFileSize(db_file); |
230 | 265 |
231 DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size); | 266 DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size); |
232 Send(reply_msg); | 267 Send(reply_msg); |
233 } | 268 } |
234 | 269 |
270 void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable( | |
271 const string16& origin_identifier, IPC::Message* reply_msg) { | |
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
273 DCHECK(db_tracker_->quota_manager_proxy()); | |
274 | |
275 QuotaManager* quota_manager = | |
276 db_tracker_->quota_manager_proxy()->quota_manager(); | |
277 if (!quota_manager) { | |
278 NOTREACHED(); // The system is shutting down, messages are unexpected. | |
279 DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(reply_msg, 0LL); | |
280 Send(reply_msg); | |
281 return; | |
282 } | |
283 | |
284 // TODO(michaeln): Is there a different API that should be used for this? | |
285 quota_manager->GetUsageAndQuota( | |
michaeln
2011/05/19 07:03:34
Hi Kinuko, my local build got into an odd state wh
| |
286 DatabaseUtil::GetOriginFromIdentifier(origin_identifier), | |
287 quota::kStorageTypeTemporary, | |
288 new MyGetUsageAndQuotaCallback(this, reply_msg)); | |
289 } | |
290 | |
235 void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier, | 291 void DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier, |
236 const string16& database_name, | 292 const string16& database_name, |
237 const string16& description, | 293 const string16& description, |
238 int64 estimated_size) { | 294 int64 estimated_size) { |
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
240 int64 database_size = 0; | 296 int64 database_size = 0; |
241 int64 space_available = 0; | 297 int64 space_available_not_used = 0; |
242 database_connections_.AddConnection(origin_identifier, database_name); | 298 database_connections_.AddConnection(origin_identifier, database_name); |
243 db_tracker_->DatabaseOpened(origin_identifier, database_name, description, | 299 db_tracker_->DatabaseOpened(origin_identifier, database_name, description, |
244 estimated_size, &database_size, &space_available); | 300 estimated_size, &database_size, |
301 &space_available_not_used); | |
245 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, | 302 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, |
246 database_size, space_available)); | 303 database_size)); |
247 } | 304 } |
248 | 305 |
249 void DatabaseMessageFilter::OnDatabaseModified( | 306 void DatabaseMessageFilter::OnDatabaseModified( |
250 const string16& origin_identifier, | 307 const string16& origin_identifier, |
251 const string16& database_name) { | 308 const string16& database_name) { |
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
253 if (!database_connections_.IsDatabaseOpened( | 310 if (!database_connections_.IsDatabaseOpened( |
254 origin_identifier, database_name)) { | 311 origin_identifier, database_name)) { |
255 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); | 312 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_DBMF")); |
256 BadMessageReceived(); | 313 BadMessageReceived(); |
(...skipping 14 matching lines...) Expand all Loading... | |
271 } | 328 } |
272 | 329 |
273 db_tracker_->DatabaseClosed(origin_identifier, database_name); | 330 db_tracker_->DatabaseClosed(origin_identifier, database_name); |
274 database_connections_.RemoveConnection(origin_identifier, database_name); | 331 database_connections_.RemoveConnection(origin_identifier, database_name); |
275 } | 332 } |
276 | 333 |
277 void DatabaseMessageFilter::OnDatabaseSizeChanged( | 334 void DatabaseMessageFilter::OnDatabaseSizeChanged( |
278 const string16& origin_identifier, | 335 const string16& origin_identifier, |
279 const string16& database_name, | 336 const string16& database_name, |
280 int64 database_size, | 337 int64 database_size, |
281 int64 space_available) { | 338 int64 space_available_not_used) { |
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
283 if (database_connections_.IsOriginUsed(origin_identifier)) { | 340 if (database_connections_.IsOriginUsed(origin_identifier)) { |
284 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, | 341 Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name, |
285 database_size, space_available)); | 342 database_size)); |
286 } | 343 } |
287 } | 344 } |
288 | 345 |
289 void DatabaseMessageFilter::OnDatabaseScheduledForDeletion( | 346 void DatabaseMessageFilter::OnDatabaseScheduledForDeletion( |
290 const string16& origin_identifier, | 347 const string16& origin_identifier, |
291 const string16& database_name) { | 348 const string16& database_name) { |
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
293 Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name)); | 350 Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name)); |
294 } | 351 } |
OLD | NEW |