Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: content/browser/in_process_webkit/indexed_db_dispatcher_host.cc

Issue 17840006: Move IndexedDB files out of in_process_webkit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "content/browser/in_process_webkit/indexed_db_dispatcher_host.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/process.h"
13 #include "base/process_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/in_process_webkit/indexed_db_callbacks.h"
16 #include "content/browser/in_process_webkit/indexed_db_database_callbacks.h"
17 #include "content/browser/indexed_db/indexed_db_context_impl.h"
18 #include "content/browser/indexed_db/indexed_db_metadata.h"
19 #include "content/browser/indexed_db/webidbcursor_impl.h"
20 #include "content/browser/indexed_db/webidbcursor_impl.h"
21 #include "content/browser/indexed_db/webidbdatabase_impl.h"
22 #include "content/browser/renderer_host/render_message_filter.h"
23 #include "content/common/indexed_db/indexed_db_messages.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/user_metrics.h"
26 #include "content/public/common/content_switches.h"
27 #include "content/public/common/result_codes.h"
28 #include "googleurl/src/gurl.h"
29 #include "third_party/WebKit/public/platform/WebIDBDatabase.h"
30 #include "third_party/WebKit/public/platform/WebIDBDatabaseError.h"
31 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
32 #include "webkit/browser/database/database_util.h"
33 #include "webkit/common/database/database_identifier.h"
34
35 using webkit_database::DatabaseUtil;
36 using WebKit::WebIDBDatabaseError;
37 using WebKit::WebIDBKey;
38
39 namespace content {
40
41 IndexedDBDispatcherHost::IndexedDBDispatcherHost(
42 int ipc_process_id,
43 IndexedDBContextImpl* indexed_db_context)
44 : indexed_db_context_(indexed_db_context),
45 database_dispatcher_host_(new DatabaseDispatcherHost(this)),
46 cursor_dispatcher_host_(new CursorDispatcherHost(this)),
47 ipc_process_id_(ipc_process_id) {
48 DCHECK(indexed_db_context_.get());
49 }
50
51 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {}
52
53 void IndexedDBDispatcherHost::OnChannelClosing() {
54 BrowserMessageFilter::OnChannelClosing();
55
56 bool success = indexed_db_context_->TaskRunner()->PostTask(
57 FROM_HERE,
58 base::Bind(&IndexedDBDispatcherHost::ResetDispatcherHosts, this));
59
60 if (!success)
61 ResetDispatcherHosts();
62 }
63
64 void IndexedDBDispatcherHost::OnDestruct() const {
65 // The last reference to the dispatcher may be a posted task, which would
66 // be destructed on the IndexedDB thread. Without this override, that would
67 // take the dispatcher with it. Since the dispatcher may be keeping the
68 // IndexedDBContext alive, it might be destructed to on its own thread,
69 // which is not supported. Ensure destruction runs on the IO thread instead.
70 BrowserThread::DeleteOnIOThread::Destruct(this);
71 }
72
73 void IndexedDBDispatcherHost::ResetDispatcherHosts() {
74 // It is important that the various *_dispatcher_host_ members are reset
75 // on the IndexedDB thread, since there might be incoming messages on that
76 // thread, and we must not reset the dispatcher hosts until after those
77 // messages are processed.
78 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
79
80 // Note that we explicitly separate CloseAll() from destruction of the
81 // DatabaseDispatcherHost, since CloseAll() can invoke callbacks which need to
82 // be dispatched through database_dispatcher_host_.
83 database_dispatcher_host_->CloseAll();
84 database_dispatcher_host_.reset();
85 cursor_dispatcher_host_.reset();
86 }
87
88 base::TaskRunner* IndexedDBDispatcherHost::OverrideTaskRunnerForMessage(
89 const IPC::Message& message) {
90 if (IPC_MESSAGE_CLASS(message) == IndexedDBMsgStart)
91 return indexed_db_context_->TaskRunner();
92 return NULL;
93 }
94
95 bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message,
96 bool* message_was_ok) {
97 if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
98 return false;
99
100 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
101
102 bool handled =
103 database_dispatcher_host_->OnMessageReceived(message, message_was_ok) ||
104 cursor_dispatcher_host_->OnMessageReceived(message, message_was_ok);
105
106 if (!handled) {
107 handled = true;
108 IPC_BEGIN_MESSAGE_MAP_EX(IndexedDBDispatcherHost, message, *message_was_ok)
109 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryGetDatabaseNames,
110 OnIDBFactoryGetDatabaseNames)
111 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryOpen, OnIDBFactoryOpen)
112 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryDeleteDatabase,
113 OnIDBFactoryDeleteDatabase)
114 IPC_MESSAGE_UNHANDLED(handled = false)
115 IPC_END_MESSAGE_MAP()
116 }
117 return handled;
118 }
119
120 int32 IndexedDBDispatcherHost::Add(WebIDBCursorImpl* idb_cursor) {
121 if (!cursor_dispatcher_host_) {
122 delete idb_cursor;
123 return 0;
124 }
125 return cursor_dispatcher_host_->map_.Add(idb_cursor);
126 }
127
128 int32 IndexedDBDispatcherHost::Add(WebIDBDatabaseImpl* idb_database,
129 int32 ipc_thread_id,
130 const GURL& origin_url) {
131 if (!database_dispatcher_host_) {
132 delete idb_database;
133 return 0;
134 }
135 int32 ipc_database_id = database_dispatcher_host_->map_.Add(idb_database);
136 Context()->ConnectionOpened(origin_url, idb_database);
137 database_dispatcher_host_->database_url_map_[ipc_database_id] = origin_url;
138 return ipc_database_id;
139 }
140
141 void IndexedDBDispatcherHost::RegisterTransactionId(int64 host_transaction_id,
142 const GURL& url) {
143 if (!database_dispatcher_host_)
144 return;
145 database_dispatcher_host_->transaction_url_map_[host_transaction_id] = url;
146 }
147
148 int64 IndexedDBDispatcherHost::HostTransactionId(int64 transaction_id) {
149 // Inject the renderer process id into the transaction id, to
150 // uniquely identify this transaction, and effectively bind it to
151 // the renderer that initiated it. The lower 32 bits of
152 // transaction_id are guaranteed to be unique within that renderer.
153 base::ProcessId pid = base::GetProcId(peer_handle());
154 DCHECK(!(transaction_id >> 32)) << "Transaction ids can only be 32 bits";
155 COMPILE_ASSERT(sizeof(base::ProcessId) <= sizeof(int32),
156 Process_ID_must_fit_in_32_bits);
157
158 return transaction_id | (static_cast<uint64>(pid) << 32);
159 }
160
161 int64 IndexedDBDispatcherHost::RendererTransactionId(
162 int64 host_transaction_id) {
163 DCHECK(host_transaction_id >> 32 == base::GetProcId(peer_handle()))
164 << "Invalid renderer target for transaction id";
165 return host_transaction_id & 0xffffffff;
166 }
167
168 WebIDBCursorImpl* IndexedDBDispatcherHost::GetCursorFromId(
169 int32 ipc_cursor_id) {
170 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
171 return cursor_dispatcher_host_->map_.Lookup(ipc_cursor_id);
172 }
173
174 ::IndexedDBDatabaseMetadata IndexedDBDispatcherHost::ConvertMetadata(
175 const content::IndexedDBDatabaseMetadata& web_metadata) {
176 ::IndexedDBDatabaseMetadata metadata;
177 metadata.id = web_metadata.id;
178 metadata.name = web_metadata.name;
179 metadata.version = web_metadata.version;
180 metadata.int_version = web_metadata.int_version;
181 metadata.max_object_store_id = web_metadata.max_object_store_id;
182
183 for (content::IndexedDBDatabaseMetadata::ObjectStoreMap::const_iterator iter =
184 web_metadata.object_stores.begin();
185 iter != web_metadata.object_stores.end();
186 ++iter) {
187
188 const content::IndexedDBObjectStoreMetadata& web_store_metadata =
189 iter->second;
190 ::IndexedDBObjectStoreMetadata idb_store_metadata;
191 idb_store_metadata.id = web_store_metadata.id;
192 idb_store_metadata.name = web_store_metadata.name;
193 idb_store_metadata.keyPath = web_store_metadata.key_path;
194 idb_store_metadata.autoIncrement = web_store_metadata.auto_increment;
195 idb_store_metadata.max_index_id = web_store_metadata.max_index_id;
196
197 for (content::IndexedDBObjectStoreMetadata::IndexMap::const_iterator
198 index_iter = web_store_metadata.indexes.begin();
199 index_iter != web_store_metadata.indexes.end();
200 ++index_iter) {
201 const content::IndexedDBIndexMetadata& web_index_metadata =
202 index_iter->second;
203 ::IndexedDBIndexMetadata idb_index_metadata;
204 idb_index_metadata.id = web_index_metadata.id;
205 idb_index_metadata.name = web_index_metadata.name;
206 idb_index_metadata.keyPath = web_index_metadata.key_path;
207 idb_index_metadata.unique = web_index_metadata.unique;
208 idb_index_metadata.multiEntry = web_index_metadata.multi_entry;
209 idb_store_metadata.indexes.push_back(idb_index_metadata);
210 }
211 metadata.object_stores.push_back(idb_store_metadata);
212 }
213 return metadata;
214 }
215
216 void IndexedDBDispatcherHost::OnIDBFactoryGetDatabaseNames(
217 const IndexedDBHostMsg_FactoryGetDatabaseNames_Params& params) {
218 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
219 base::FilePath indexed_db_path = indexed_db_context_->data_path();
220
221 Context()->GetIDBFactory()->getDatabaseNames(
222 new IndexedDBCallbacks<std::vector<string16> >(
223 this, params.ipc_thread_id, params.ipc_callbacks_id),
224 WebKit::WebString::fromUTF8(params.database_identifier),
225 indexed_db_path.AsUTF16Unsafe());
226 }
227
228 void IndexedDBDispatcherHost::OnIDBFactoryOpen(
229 const IndexedDBHostMsg_FactoryOpen_Params& params) {
230 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
231 base::FilePath indexed_db_path = indexed_db_context_->data_path();
232
233 GURL origin_url =
234 webkit_database::GetOriginFromIdentifier(params.database_identifier);
235
236 int64 host_transaction_id = HostTransactionId(params.transaction_id);
237
238 // TODO(dgrogan): Don't let a non-existing database be opened (and therefore
239 // created) if this origin is already over quota.
240 Context()->GetIDBFactory()
241 ->open(params.name,
242 params.version,
243 host_transaction_id,
244 new IndexedDBCallbacksDatabase(this,
245 params.ipc_thread_id,
246 params.ipc_callbacks_id,
247 params.ipc_database_callbacks_id,
248 host_transaction_id,
249 origin_url),
250 new IndexedDBDatabaseCallbacks(
251 this, params.ipc_thread_id, params.ipc_database_callbacks_id),
252 WebKit::WebString::fromUTF8(params.database_identifier),
253 indexed_db_path.AsUTF16Unsafe());
254 }
255
256 void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
257 const IndexedDBHostMsg_FactoryDeleteDatabase_Params& params) {
258 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
259 base::FilePath indexed_db_path = indexed_db_context_->data_path();
260
261 Context()->GetIDBFactory()
262 ->deleteDatabase(params.name,
263 new IndexedDBCallbacks<std::vector<char> >(
264 this, params.ipc_thread_id, params.ipc_callbacks_id),
265 WebKit::WebString::fromUTF8(params.database_identifier),
266 indexed_db_path.AsUTF16Unsafe());
267 }
268
269 void IndexedDBDispatcherHost::FinishTransaction(int64 host_transaction_id,
270 bool committed) {
271 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
272 TransactionIDToURLMap& transaction_url_map =
273 database_dispatcher_host_->transaction_url_map_;
274 TransactionIDToSizeMap& transaction_size_map =
275 database_dispatcher_host_->transaction_size_map_;
276 TransactionIDToDatabaseIDMap& transaction_database_map =
277 database_dispatcher_host_->transaction_database_map_;
278 if (committed)
279 Context()->TransactionComplete(transaction_url_map[host_transaction_id]);
280 // It's unclear if std::map::erase(key) has defined behavior if the
281 // key is not found.
282 // TODO(alecflett): Remove if it is proven that it is safe.
283 if (transaction_url_map.find(host_transaction_id) !=
284 transaction_url_map.end())
285 transaction_url_map.erase(host_transaction_id);
286 if (transaction_size_map.find(host_transaction_id) !=
287 transaction_size_map.end())
288 transaction_size_map.erase(host_transaction_id);
289 if (transaction_database_map.find(host_transaction_id) !=
290 transaction_database_map.end())
291 transaction_database_map.erase(host_transaction_id);
292 }
293
294 //////////////////////////////////////////////////////////////////////
295 // Helper templates.
296 //
297
298 template <typename ObjectType>
299 ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
300 IDMap<ObjectType, IDMapOwnPointer>* map,
301 int32 ipc_return_object_id) {
302 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
303 ObjectType* return_object = map->Lookup(ipc_return_object_id);
304 if (!return_object) {
305 NOTREACHED() << "Uh oh, couldn't find object with id "
306 << ipc_return_object_id;
307 RecordAction(UserMetricsAction("BadMessageTerminate_IDBMF"));
308 BadMessageReceived();
309 }
310 return return_object;
311 }
312
313 template <typename ObjectType>
314 void IndexedDBDispatcherHost::DestroyObject(
315 IDMap<ObjectType, IDMapOwnPointer>* map,
316 int32 ipc_object_id) {
317 GetOrTerminateProcess(map, ipc_object_id);
318 map->Remove(ipc_object_id);
319 }
320
321 //////////////////////////////////////////////////////////////////////
322 // IndexedDBDispatcherHost::DatabaseDispatcherHost
323 //
324
325 IndexedDBDispatcherHost::DatabaseDispatcherHost::DatabaseDispatcherHost(
326 IndexedDBDispatcherHost* parent)
327 : parent_(parent) {
328 map_.set_check_on_null_data(true);
329 }
330
331 IndexedDBDispatcherHost::DatabaseDispatcherHost::~DatabaseDispatcherHost() {
332 // TODO(alecflett): uncomment these when we find the source of these leaks.
333 // DCHECK(transaction_size_map_.empty());
334 // DCHECK(transaction_url_map_.empty());
335 }
336
337 void IndexedDBDispatcherHost::DatabaseDispatcherHost::CloseAll() {
338 DCHECK(
339 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
340 // Abort outstanding transactions started by connections in the associated
341 // front-end to unblock later transactions. This should only occur on unclean
342 // (crash) or abrupt (process-kill) shutdowns.
343 for (TransactionIDToDatabaseIDMap::iterator iter =
344 transaction_database_map_.begin();
345 iter != transaction_database_map_.end();) {
346 int64 transaction_id = iter->first;
347 int32 ipc_database_id = iter->second;
348 ++iter;
349 WebIDBDatabaseImpl* database = map_.Lookup(ipc_database_id);
350 if (database) {
351 database->abort(
352 transaction_id,
353 WebIDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError));
354 }
355 }
356 DCHECK(transaction_database_map_.empty());
357
358 for (WebIDBObjectIDToURLMap::iterator iter = database_url_map_.begin();
359 iter != database_url_map_.end();
360 iter++) {
361 WebIDBDatabaseImpl* database = map_.Lookup(iter->first);
362 if (database) {
363 database->close();
364 parent_->Context()->ConnectionClosed(iter->second, database);
365 }
366 }
367 }
368
369 bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
370 const IPC::Message& message,
371 bool* msg_is_ok) {
372 DCHECK(
373 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
374 bool handled = true;
375 IPC_BEGIN_MESSAGE_MAP_EX(
376 IndexedDBDispatcherHost::DatabaseDispatcherHost, message, *msg_is_ok)
377 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateObjectStore,
378 OnCreateObjectStore)
379 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteObjectStore,
380 OnDeleteObjectStore)
381 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateTransaction,
382 OnCreateTransaction)
383 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseClose, OnClose)
384 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDestroyed, OnDestroyed)
385 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseGet, OnGet)
386 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabasePut, OnPut)
387 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexKeys, OnSetIndexKeys)
388 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexesReady,
389 OnSetIndexesReady)
390 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseOpenCursor, OnOpenCursor)
391 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCount, OnCount)
392 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteRange, OnDeleteRange)
393 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseClear, OnClear)
394 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateIndex, OnCreateIndex)
395 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteIndex, OnDeleteIndex)
396 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseAbort, OnAbort)
397 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCommit, OnCommit)
398 IPC_MESSAGE_UNHANDLED(handled = false)
399 IPC_END_MESSAGE_MAP()
400 return handled;
401 }
402
403 void IndexedDBDispatcherHost::DatabaseDispatcherHost::Send(
404 IPC::Message* message) {
405 parent_->Send(message);
406 }
407
408 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateObjectStore(
409 const IndexedDBHostMsg_DatabaseCreateObjectStore_Params& params) {
410 DCHECK(
411 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
412 WebIDBDatabaseImpl* database =
413 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
414 if (!database)
415 return;
416
417 int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
418 database->createObjectStore(host_transaction_id,
419 params.object_store_id,
420 params.name,
421 params.key_path,
422 params.auto_increment);
423 if (parent_->Context()->IsOverQuota(
424 database_url_map_[params.ipc_database_id])) {
425 database->abort(
426 host_transaction_id,
427 WebIDBDatabaseError(WebKit::WebIDBDatabaseExceptionQuotaError));
428 }
429 }
430
431 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteObjectStore(
432 int32 ipc_database_id,
433 int64 transaction_id,
434 int64 object_store_id) {
435 DCHECK(
436 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
437 WebIDBDatabaseImpl* database =
438 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
439 if (!database)
440 return;
441
442 database->deleteObjectStore(parent_->HostTransactionId(transaction_id),
443 object_store_id);
444 }
445
446 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateTransaction(
447 const IndexedDBHostMsg_DatabaseCreateTransaction_Params& params) {
448 DCHECK(
449 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
450 WebIDBDatabaseImpl* database =
451 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
452 if (!database)
453 return;
454
455 int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
456
457 database->createTransaction(
458 host_transaction_id,
459 new IndexedDBDatabaseCallbacks(
460 parent_, params.ipc_thread_id, params.ipc_database_callbacks_id),
461 params.object_store_ids,
462 params.mode);
463 transaction_database_map_[host_transaction_id] = params.ipc_database_id;
464 parent_->RegisterTransactionId(host_transaction_id,
465 database_url_map_[params.ipc_database_id]);
466 }
467
468 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClose(
469 int32 ipc_database_id) {
470 DCHECK(
471 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
472 WebIDBDatabaseImpl* database =
473 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
474 if (!database)
475 return;
476 database->close();
477 }
478
479 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDestroyed(
480 int32 ipc_object_id) {
481 DCHECK(
482 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
483 WebIDBDatabaseImpl* database = map_.Lookup(ipc_object_id);
484 parent_->Context()
485 ->ConnectionClosed(database_url_map_[ipc_object_id], database);
486 database_url_map_.erase(ipc_object_id);
487 parent_->DestroyObject(&map_, ipc_object_id);
488 }
489
490 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGet(
491 const IndexedDBHostMsg_DatabaseGet_Params& params) {
492 DCHECK(
493 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
494 WebIDBDatabaseImpl* database =
495 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
496 if (!database)
497 return;
498
499 scoped_ptr<IndexedDBCallbacksBase> callbacks(
500 new IndexedDBCallbacks<std::vector<char> >(
501 parent_, params.ipc_thread_id, params.ipc_callbacks_id));
502 database->get(parent_->HostTransactionId(params.transaction_id),
503 params.object_store_id,
504 params.index_id,
505 params.key_range,
506 params.key_only,
507 callbacks.release());
508 }
509
510 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(
511 const IndexedDBHostMsg_DatabasePut_Params& params) {
512 DCHECK(
513 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
514
515 WebIDBDatabaseImpl* database =
516 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
517 if (!database)
518 return;
519 scoped_ptr<IndexedDBCallbacksBase> callbacks(
520 new IndexedDBCallbacks<IndexedDBKey>(
521 parent_, params.ipc_thread_id, params.ipc_callbacks_id));
522
523 int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
524 // TODO(alecflett): Avoid a copy here.
525 std::vector<char> value_copy = params.value;
526 database->put(host_transaction_id,
527 params.object_store_id,
528 &value_copy,
529 params.key,
530 params.put_mode,
531 callbacks.release(),
532 params.index_ids,
533 params.index_keys);
534 TransactionIDToSizeMap* map =
535 &parent_->database_dispatcher_host_->transaction_size_map_;
536 // Size can't be big enough to overflow because it represents the
537 // actual bytes passed through IPC.
538 (*map)[host_transaction_id] += params.value.size();
539 }
540
541 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexKeys(
542 const IndexedDBHostMsg_DatabaseSetIndexKeys_Params& params) {
543 DCHECK(
544 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
545 WebIDBDatabaseImpl* database =
546 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
547 if (!database)
548 return;
549
550 int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
551 if (params.index_ids.size() != params.index_keys.size()) {
552 database->abort(
553 host_transaction_id,
554 WebIDBDatabaseError(
555 WebKit::WebIDBDatabaseExceptionUnknownError,
556 "Malformed IPC message: index_ids.size() != index_keys.size()"));
557 return;
558 }
559
560 database->setIndexKeys(host_transaction_id,
561 params.object_store_id,
562 params.primary_key,
563 params.index_ids,
564 params.index_keys);
565 }
566
567 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexesReady(
568 int32 ipc_database_id,
569 int64 transaction_id,
570 int64 object_store_id,
571 const std::vector<int64>& index_ids) {
572 DCHECK(
573 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
574 WebIDBDatabaseImpl* database =
575 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
576 if (!database)
577 return;
578
579 database->setIndexesReady(
580 parent_->HostTransactionId(transaction_id), object_store_id, index_ids);
581 }
582
583 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnOpenCursor(
584 const IndexedDBHostMsg_DatabaseOpenCursor_Params& params) {
585 DCHECK(
586 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
587 WebIDBDatabaseImpl* database =
588 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
589 if (!database)
590 return;
591
592 scoped_ptr<IndexedDBCallbacksBase> callbacks(
593 new IndexedDBCallbacks<WebIDBCursorImpl>(
594 parent_, params.ipc_thread_id, params.ipc_callbacks_id, -1));
595 database->openCursor(parent_->HostTransactionId(params.transaction_id),
596 params.object_store_id,
597 params.index_id,
598 params.key_range,
599 params.direction,
600 params.key_only,
601 params.task_type,
602 callbacks.release());
603 }
604
605 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCount(
606 const IndexedDBHostMsg_DatabaseCount_Params& params) {
607 DCHECK(
608 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
609 WebIDBDatabaseImpl* database =
610 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
611 if (!database)
612 return;
613
614 scoped_ptr<IndexedDBCallbacksBase> callbacks(
615 new IndexedDBCallbacks<std::vector<char> >(
616 parent_, params.ipc_thread_id, params.ipc_callbacks_id));
617 database->count(parent_->HostTransactionId(params.transaction_id),
618 params.object_store_id,
619 params.index_id,
620 params.key_range,
621 callbacks.release());
622 }
623
624 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteRange(
625 const IndexedDBHostMsg_DatabaseDeleteRange_Params& params) {
626 DCHECK(
627 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
628 WebIDBDatabaseImpl* database =
629 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
630 if (!database)
631 return;
632
633 scoped_ptr<IndexedDBCallbacksBase> callbacks(
634 new IndexedDBCallbacks<std::vector<char> >(
635 parent_, params.ipc_thread_id, params.ipc_callbacks_id));
636 database->deleteRange(parent_->HostTransactionId(params.transaction_id),
637 params.object_store_id,
638 params.key_range,
639 callbacks.release());
640 }
641
642 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClear(
643 int32 ipc_thread_id,
644 int32 ipc_callbacks_id,
645 int32 ipc_database_id,
646 int64 transaction_id,
647 int64 object_store_id) {
648 DCHECK(
649 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
650 WebIDBDatabaseImpl* database =
651 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
652 if (!database)
653 return;
654
655 scoped_ptr<IndexedDBCallbacksBase> callbacks(
656 new IndexedDBCallbacks<std::vector<char> >(
657 parent_, ipc_thread_id, ipc_callbacks_id));
658
659 database->clear(parent_->HostTransactionId(transaction_id),
660 object_store_id,
661 callbacks.release());
662 }
663
664 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnAbort(
665 int32 ipc_database_id,
666 int64 transaction_id) {
667 DCHECK(
668 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
669 WebIDBDatabaseImpl* database =
670 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
671 if (!database)
672 return;
673
674 database->abort(parent_->HostTransactionId(transaction_id));
675 }
676
677 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCommit(
678 int32 ipc_database_id,
679 int64 transaction_id) {
680 DCHECK(
681 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
682 WebIDBDatabaseImpl* database =
683 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
684 if (!database)
685 return;
686
687 int64 host_transaction_id = parent_->HostTransactionId(transaction_id);
688 int64 transaction_size = transaction_size_map_[host_transaction_id];
689 if (transaction_size &&
690 parent_->Context()->WouldBeOverQuota(
691 transaction_url_map_[host_transaction_id], transaction_size)) {
692 database->abort(
693 host_transaction_id,
694 WebIDBDatabaseError(WebKit::WebIDBDatabaseExceptionQuotaError));
695 return;
696 }
697
698 database->commit(host_transaction_id);
699 }
700
701 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateIndex(
702 const IndexedDBHostMsg_DatabaseCreateIndex_Params& params) {
703 DCHECK(
704 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
705 WebIDBDatabaseImpl* database =
706 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
707 if (!database)
708 return;
709
710 int64 host_transaction_id = parent_->HostTransactionId(params.transaction_id);
711 database->createIndex(host_transaction_id,
712 params.object_store_id,
713 params.index_id,
714 params.name,
715 params.key_path,
716 params.unique,
717 params.multi_entry);
718 if (parent_->Context()->IsOverQuota(
719 database_url_map_[params.ipc_database_id])) {
720 database->abort(
721 host_transaction_id,
722 WebIDBDatabaseError(WebKit::WebIDBDatabaseExceptionQuotaError));
723 }
724 }
725
726 void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteIndex(
727 int32 ipc_database_id,
728 int64 transaction_id,
729 int64 object_store_id,
730 int64 index_id) {
731 DCHECK(
732 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
733 WebIDBDatabaseImpl* database =
734 parent_->GetOrTerminateProcess(&map_, ipc_database_id);
735 if (!database)
736 return;
737
738 database->deleteIndex(
739 parent_->HostTransactionId(transaction_id), object_store_id, index_id);
740 }
741
742 //////////////////////////////////////////////////////////////////////
743 // IndexedDBDispatcherHost::CursorDispatcherHost
744 //
745
746 IndexedDBDispatcherHost::CursorDispatcherHost::CursorDispatcherHost(
747 IndexedDBDispatcherHost* parent)
748 : parent_(parent) {
749 map_.set_check_on_null_data(true);
750 }
751
752 IndexedDBDispatcherHost::CursorDispatcherHost::~CursorDispatcherHost() {}
753
754 bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
755 const IPC::Message& message,
756 bool* msg_is_ok) {
757 DCHECK(
758 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
759
760 bool handled = true;
761 IPC_BEGIN_MESSAGE_MAP_EX(
762 IndexedDBDispatcherHost::CursorDispatcherHost, message, *msg_is_ok)
763 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorAdvance, OnAdvance)
764 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorContinue, OnContinue)
765 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetch, OnPrefetch)
766 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetchReset, OnPrefetchReset)
767 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDestroyed, OnDestroyed)
768 IPC_MESSAGE_UNHANDLED(handled = false)
769 IPC_END_MESSAGE_MAP()
770 return handled;
771 }
772
773 void IndexedDBDispatcherHost::CursorDispatcherHost::Send(
774 IPC::Message* message) {
775 parent_->Send(message);
776 }
777
778 void IndexedDBDispatcherHost::CursorDispatcherHost::OnAdvance(
779 int32 ipc_cursor_id,
780 int32 ipc_thread_id,
781 int32 ipc_callbacks_id,
782 unsigned long count) {
783 DCHECK(
784 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
785 WebIDBCursorImpl* idb_cursor =
786 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
787 if (!idb_cursor)
788 return;
789
790 idb_cursor->advance(
791 count,
792 new IndexedDBCallbacks<WebIDBCursorImpl>(
793 parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
794 }
795
796 void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
797 int32 ipc_cursor_id,
798 int32 ipc_thread_id,
799 int32 ipc_callbacks_id,
800 const IndexedDBKey& key) {
801 DCHECK(
802 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
803 WebIDBCursorImpl* idb_cursor =
804 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
805 if (!idb_cursor)
806 return;
807
808 idb_cursor->continueFunction(
809 key,
810 new IndexedDBCallbacks<WebIDBCursorImpl>(
811 parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
812 }
813
814 void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
815 int32 ipc_cursor_id,
816 int32 ipc_thread_id,
817 int32 ipc_callbacks_id,
818 int n) {
819 DCHECK(
820 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
821 WebIDBCursorImpl* idb_cursor =
822 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
823 if (!idb_cursor)
824 return;
825
826 idb_cursor->prefetchContinue(
827 n,
828 new IndexedDBCallbacks<WebIDBCursorImpl>(
829 parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
830 }
831
832 void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
833 int32 ipc_cursor_id,
834 int used_prefetches,
835 int unused_prefetches) {
836 DCHECK(
837 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
838 WebIDBCursorImpl* idb_cursor =
839 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
840 if (!idb_cursor)
841 return;
842
843 idb_cursor->prefetchReset(used_prefetches, unused_prefetches);
844 }
845
846 void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed(
847 int32 ipc_object_id) {
848 DCHECK(
849 parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
850 parent_->DestroyObject(&map_, ipc_object_id);
851 }
852
853 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698