OLD | NEW |
| (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/common_child/indexed_db/indexed_db_dispatcher.h" | |
6 | |
7 #include "base/format_macros.h" | |
8 #include "base/lazy_instance.h" | |
9 #include "base/stringprintf.h" | |
10 #include "base/threading/thread_local.h" | |
11 #include "content/common/child_thread.h" | |
12 #include "content/common/indexed_db/indexed_db_messages.h" | |
13 #include "content/common_child/indexed_db/proxy_webidbcursor_impl.h" | |
14 #include "content/common_child/indexed_db/proxy_webidbdatabase_impl.h" | |
15 #include "ipc/ipc_channel.h" | |
16 #include "third_party/WebKit/public/platform/WebIDBDatabaseCallbacks.h" | |
17 #include "third_party/WebKit/public/platform/WebIDBDatabaseError.h" | |
18 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" | |
19 #include "third_party/WebKit/public/platform/WebIDBKeyRange.h" | |
20 | |
21 using WebKit::WebData; | |
22 using WebKit::WebIDBCallbacks; | |
23 using WebKit::WebIDBDatabase; | |
24 using WebKit::WebIDBDatabaseCallbacks; | |
25 using WebKit::WebIDBDatabaseError; | |
26 using WebKit::WebIDBKey; | |
27 using WebKit::WebIDBKeyRange; | |
28 using WebKit::WebIDBMetadata; | |
29 using WebKit::WebString; | |
30 using WebKit::WebVector; | |
31 using base::ThreadLocalPointer; | |
32 using webkit_glue::WorkerTaskRunner; | |
33 | |
34 namespace content { | |
35 static base::LazyInstance<ThreadLocalPointer<IndexedDBDispatcher> >::Leaky | |
36 g_idb_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; | |
37 | |
38 namespace { | |
39 | |
40 IndexedDBDispatcher* const kHasBeenDeleted = | |
41 reinterpret_cast<IndexedDBDispatcher*>(0x1); | |
42 | |
43 int32 CurrentWorkerId() { | |
44 return WorkerTaskRunner::Instance()->CurrentWorkerId(); | |
45 } | |
46 } // unnamed namespace | |
47 | |
48 const size_t kMaxIDBValueSizeInBytes = 64 * 1024 * 1024; | |
49 | |
50 IndexedDBDispatcher::IndexedDBDispatcher() { | |
51 g_idb_dispatcher_tls.Pointer()->Set(this); | |
52 } | |
53 | |
54 IndexedDBDispatcher::~IndexedDBDispatcher() { | |
55 // Clear any pending callbacks - which may result in dispatch requests - | |
56 // before marking the dispatcher as deleted. | |
57 pending_callbacks_.Clear(); | |
58 pending_database_callbacks_.Clear(); | |
59 | |
60 DCHECK(pending_callbacks_.IsEmpty()); | |
61 DCHECK(pending_database_callbacks_.IsEmpty()); | |
62 | |
63 g_idb_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); | |
64 } | |
65 | |
66 IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance() { | |
67 if (g_idb_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { | |
68 NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher."; | |
69 g_idb_dispatcher_tls.Pointer()->Set(NULL); | |
70 } | |
71 if (g_idb_dispatcher_tls.Pointer()->Get()) | |
72 return g_idb_dispatcher_tls.Pointer()->Get(); | |
73 | |
74 IndexedDBDispatcher* dispatcher = new IndexedDBDispatcher; | |
75 if (WorkerTaskRunner::Instance()->CurrentWorkerId()) | |
76 webkit_glue::WorkerTaskRunner::Instance()->AddStopObserver(dispatcher); | |
77 return dispatcher; | |
78 } | |
79 | |
80 void IndexedDBDispatcher::OnWorkerRunLoopStopped() { delete this; } | |
81 | |
82 WebIDBMetadata IndexedDBDispatcher::ConvertMetadata( | |
83 const IndexedDBDatabaseMetadata& idb_metadata) { | |
84 WebIDBMetadata web_metadata; | |
85 web_metadata.id = idb_metadata.id; | |
86 web_metadata.name = idb_metadata.name; | |
87 web_metadata.version = idb_metadata.version; | |
88 web_metadata.intVersion = idb_metadata.int_version; | |
89 web_metadata.maxObjectStoreId = idb_metadata.max_object_store_id; | |
90 web_metadata.objectStores = | |
91 WebVector<WebIDBMetadata::ObjectStore>(idb_metadata.object_stores.size()); | |
92 | |
93 for (size_t i = 0; i < idb_metadata.object_stores.size(); ++i) { | |
94 const IndexedDBObjectStoreMetadata& idb_store_metadata = | |
95 idb_metadata.object_stores[i]; | |
96 WebIDBMetadata::ObjectStore& web_store_metadata = | |
97 web_metadata.objectStores[i]; | |
98 | |
99 web_store_metadata.id = idb_store_metadata.id; | |
100 web_store_metadata.name = idb_store_metadata.name; | |
101 web_store_metadata.keyPath = idb_store_metadata.keyPath; | |
102 web_store_metadata.autoIncrement = idb_store_metadata.autoIncrement; | |
103 web_store_metadata.maxIndexId = idb_store_metadata.max_index_id; | |
104 web_store_metadata.indexes = | |
105 WebVector<WebIDBMetadata::Index>(idb_store_metadata.indexes.size()); | |
106 | |
107 for (size_t j = 0; j < idb_store_metadata.indexes.size(); ++j) { | |
108 const IndexedDBIndexMetadata& idb_index_metadata = | |
109 idb_store_metadata.indexes[j]; | |
110 WebIDBMetadata::Index& web_index_metadata = web_store_metadata.indexes[j]; | |
111 | |
112 web_index_metadata.id = idb_index_metadata.id; | |
113 web_index_metadata.name = idb_index_metadata.name; | |
114 web_index_metadata.keyPath = idb_index_metadata.keyPath; | |
115 web_index_metadata.unique = idb_index_metadata.unique; | |
116 web_index_metadata.multiEntry = idb_index_metadata.multiEntry; | |
117 } | |
118 } | |
119 | |
120 return web_metadata; | |
121 } | |
122 | |
123 void IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) { | |
124 bool handled = true; | |
125 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcher, msg) | |
126 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBCursor, | |
127 OnSuccessOpenCursor) | |
128 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorAdvance, | |
129 OnSuccessCursorContinue) | |
130 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorContinue, | |
131 OnSuccessCursorContinue) | |
132 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorPrefetch, | |
133 OnSuccessCursorPrefetch) | |
134 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase, | |
135 OnSuccessIDBDatabase) | |
136 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIndexedDBKey, | |
137 OnSuccessIndexedDBKey) | |
138 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessStringList, | |
139 OnSuccessStringList) | |
140 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessValue, OnSuccessValue) | |
141 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessValueWithKey, | |
142 OnSuccessValueWithKey) | |
143 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessInteger, OnSuccessInteger) | |
144 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessUndefined, | |
145 OnSuccessUndefined) | |
146 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksError, OnError) | |
147 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksIntBlocked, OnIntBlocked) | |
148 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksUpgradeNeeded, OnUpgradeNeeded) | |
149 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksForcedClose, | |
150 OnForcedClose) | |
151 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksIntVersionChange, | |
152 OnIntVersionChange) | |
153 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksAbort, OnAbort) | |
154 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksComplete, OnComplete) | |
155 IPC_MESSAGE_UNHANDLED(handled = false) | |
156 IPC_END_MESSAGE_MAP() | |
157 // If a message gets here, IndexedDBMessageFilter already determined that it | |
158 // is an IndexedDB message. | |
159 DCHECK(handled) << "Didn't handle a message defined at line " | |
160 << IPC_MESSAGE_ID_LINE(msg.type()); | |
161 } | |
162 | |
163 bool IndexedDBDispatcher::Send(IPC::Message* msg) { | |
164 if (!ChildThread::current()) { | |
165 // Unexpected - this may be happening during shutdown. | |
166 NOTREACHED(); | |
167 return false; | |
168 } | |
169 if (CurrentWorkerId()) { | |
170 scoped_refptr<IPC::SyncMessageFilter> filter( | |
171 ChildThread::current()->sync_message_filter()); | |
172 return filter->Send(msg); | |
173 } | |
174 return ChildThread::current()->Send(msg); | |
175 } | |
176 | |
177 void IndexedDBDispatcher::RequestIDBCursorAdvance( | |
178 unsigned long count, | |
179 WebIDBCallbacks* callbacks_ptr, | |
180 int32 ipc_cursor_id) { | |
181 // Reset all cursor prefetch caches except for this cursor. | |
182 ResetCursorPrefetchCaches(ipc_cursor_id); | |
183 | |
184 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
185 | |
186 int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
187 Send(new IndexedDBHostMsg_CursorAdvance( | |
188 ipc_cursor_id, CurrentWorkerId(), ipc_callbacks_id, count)); | |
189 } | |
190 | |
191 void IndexedDBDispatcher::RequestIDBCursorContinue( | |
192 const IndexedDBKey& key, | |
193 WebIDBCallbacks* callbacks_ptr, | |
194 int32 ipc_cursor_id) { | |
195 // Reset all cursor prefetch caches except for this cursor. | |
196 ResetCursorPrefetchCaches(ipc_cursor_id); | |
197 | |
198 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
199 | |
200 int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
201 Send(new IndexedDBHostMsg_CursorContinue( | |
202 ipc_cursor_id, CurrentWorkerId(), ipc_callbacks_id, key)); | |
203 } | |
204 | |
205 void IndexedDBDispatcher::RequestIDBCursorPrefetch( | |
206 int n, | |
207 WebIDBCallbacks* callbacks_ptr, | |
208 int32 ipc_cursor_id) { | |
209 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
210 | |
211 int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
212 Send(new IndexedDBHostMsg_CursorPrefetch( | |
213 ipc_cursor_id, CurrentWorkerId(), ipc_callbacks_id, n)); | |
214 } | |
215 | |
216 void IndexedDBDispatcher::RequestIDBCursorPrefetchReset(int used_prefetches, | |
217 int unused_prefetches, | |
218 int32 ipc_cursor_id) { | |
219 Send(new IndexedDBHostMsg_CursorPrefetchReset( | |
220 ipc_cursor_id, used_prefetches, unused_prefetches)); | |
221 } | |
222 | |
223 void IndexedDBDispatcher::RequestIDBFactoryOpen( | |
224 const string16& name, | |
225 int64 version, | |
226 int64 transaction_id, | |
227 WebIDBCallbacks* callbacks_ptr, | |
228 WebIDBDatabaseCallbacks* database_callbacks_ptr, | |
229 const string16& database_identifier) { | |
230 ResetCursorPrefetchCaches(); | |
231 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
232 scoped_ptr<WebIDBDatabaseCallbacks> database_callbacks( | |
233 database_callbacks_ptr); | |
234 | |
235 IndexedDBHostMsg_FactoryOpen_Params params; | |
236 params.ipc_thread_id = CurrentWorkerId(); | |
237 params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
238 params.ipc_database_callbacks_id = | |
239 pending_database_callbacks_.Add(database_callbacks.release()); | |
240 params.database_identifier = database_identifier; | |
241 params.name = name; | |
242 params.transaction_id = transaction_id; | |
243 params.version = version; | |
244 Send(new IndexedDBHostMsg_FactoryOpen(params)); | |
245 } | |
246 | |
247 void IndexedDBDispatcher::RequestIDBFactoryGetDatabaseNames( | |
248 WebIDBCallbacks* callbacks_ptr, | |
249 const string16& database_identifier) { | |
250 ResetCursorPrefetchCaches(); | |
251 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
252 | |
253 IndexedDBHostMsg_FactoryGetDatabaseNames_Params params; | |
254 params.ipc_thread_id = CurrentWorkerId(); | |
255 params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
256 params.database_identifier = database_identifier; | |
257 Send(new IndexedDBHostMsg_FactoryGetDatabaseNames(params)); | |
258 } | |
259 | |
260 void IndexedDBDispatcher::RequestIDBFactoryDeleteDatabase( | |
261 const string16& name, | |
262 WebIDBCallbacks* callbacks_ptr, | |
263 const string16& database_identifier) { | |
264 ResetCursorPrefetchCaches(); | |
265 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
266 | |
267 IndexedDBHostMsg_FactoryDeleteDatabase_Params params; | |
268 params.ipc_thread_id = CurrentWorkerId(); | |
269 params.ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
270 params.database_identifier = database_identifier; | |
271 params.name = name; | |
272 Send(new IndexedDBHostMsg_FactoryDeleteDatabase(params)); | |
273 } | |
274 | |
275 void IndexedDBDispatcher::RequestIDBDatabaseClose( | |
276 int32 ipc_database_id, | |
277 int32 ipc_database_callbacks_id) { | |
278 ResetCursorPrefetchCaches(); | |
279 Send(new IndexedDBHostMsg_DatabaseClose(ipc_database_id)); | |
280 // There won't be pending database callbacks if the transaction was aborted in | |
281 // the initial upgradeneeded event handler. | |
282 if (pending_database_callbacks_.Lookup(ipc_database_callbacks_id)) | |
283 pending_database_callbacks_.Remove(ipc_database_callbacks_id); | |
284 } | |
285 | |
286 void IndexedDBDispatcher::RequestIDBDatabaseCreateTransaction( | |
287 int32 ipc_database_id, | |
288 int64 transaction_id, | |
289 WebIDBDatabaseCallbacks* database_callbacks_ptr, | |
290 WebKit::WebVector<long long> object_store_ids, | |
291 unsigned short mode) { | |
292 scoped_ptr<WebIDBDatabaseCallbacks> database_callbacks( | |
293 database_callbacks_ptr); | |
294 IndexedDBHostMsg_DatabaseCreateTransaction_Params params; | |
295 params.ipc_thread_id = CurrentWorkerId(); | |
296 params.ipc_database_id = ipc_database_id; | |
297 params.transaction_id = transaction_id; | |
298 params.ipc_database_callbacks_id = | |
299 pending_database_callbacks_.Add(database_callbacks.release()); | |
300 params.object_store_ids | |
301 .assign(object_store_ids.data(), | |
302 object_store_ids.data() + object_store_ids.size()); | |
303 params.mode = mode; | |
304 | |
305 Send(new IndexedDBHostMsg_DatabaseCreateTransaction(params)); | |
306 } | |
307 | |
308 void IndexedDBDispatcher::RequestIDBDatabaseGet( | |
309 int32 ipc_database_id, | |
310 int64 transaction_id, | |
311 int64 object_store_id, | |
312 int64 index_id, | |
313 const IndexedDBKeyRange& key_range, | |
314 bool key_only, | |
315 WebIDBCallbacks* callbacks) { | |
316 ResetCursorPrefetchCaches(); | |
317 IndexedDBHostMsg_DatabaseGet_Params params; | |
318 init_params(params, callbacks); | |
319 params.ipc_database_id = ipc_database_id; | |
320 params.transaction_id = transaction_id; | |
321 params.object_store_id = object_store_id; | |
322 params.index_id = index_id; | |
323 params.key_range = key_range; | |
324 params.key_only = key_only; | |
325 Send(new IndexedDBHostMsg_DatabaseGet(params)); | |
326 } | |
327 | |
328 void IndexedDBDispatcher::RequestIDBDatabasePut( | |
329 int32 ipc_database_id, | |
330 int64 transaction_id, | |
331 int64 object_store_id, | |
332 const WebData& value, | |
333 const IndexedDBKey& key, | |
334 WebIDBDatabase::PutMode put_mode, | |
335 WebIDBCallbacks* callbacks, | |
336 const WebVector<long long>& index_ids, | |
337 const WebVector<WebKit::WebVector<WebIDBKey> >& index_keys) { | |
338 | |
339 if (value.size() > kMaxIDBValueSizeInBytes) { | |
340 callbacks->onError(WebIDBDatabaseError( | |
341 WebKit::WebIDBDatabaseExceptionUnknownError, | |
342 WebString::fromUTF8(base::StringPrintf( | |
343 "The serialized value is too large" | |
344 " (size=%" PRIuS " bytes, max=%" PRIuS " bytes).", | |
345 value.size(), | |
346 kMaxIDBValueSizeInBytes).c_str()))); | |
347 return; | |
348 } | |
349 | |
350 ResetCursorPrefetchCaches(); | |
351 IndexedDBHostMsg_DatabasePut_Params params; | |
352 init_params(params, callbacks); | |
353 params.ipc_database_id = ipc_database_id; | |
354 params.transaction_id = transaction_id; | |
355 params.object_store_id = object_store_id; | |
356 | |
357 params.value.assign(value.data(), value.data() + value.size()); | |
358 params.key = key; | |
359 params.put_mode = put_mode; | |
360 | |
361 COMPILE_ASSERT(sizeof(params.index_ids[0]) == sizeof(index_ids[0]), | |
362 Cant_copy); | |
363 params.index_ids | |
364 .assign(index_ids.data(), index_ids.data() + index_ids.size()); | |
365 | |
366 params.index_keys.resize(index_keys.size()); | |
367 for (size_t i = 0; i < index_keys.size(); ++i) { | |
368 params.index_keys[i].resize(index_keys[i].size()); | |
369 for (size_t j = 0; j < index_keys[i].size(); ++j) { | |
370 params.index_keys[i][j] = IndexedDBKey(index_keys[i][j]); | |
371 } | |
372 } | |
373 Send(new IndexedDBHostMsg_DatabasePut(params)); | |
374 } | |
375 | |
376 void IndexedDBDispatcher::RequestIDBDatabaseOpenCursor( | |
377 int32 ipc_database_id, | |
378 int64 transaction_id, | |
379 int64 object_store_id, | |
380 int64 index_id, | |
381 const IndexedDBKeyRange& key_range, | |
382 unsigned short direction, | |
383 bool key_only, | |
384 WebKit::WebIDBDatabase::TaskType task_type, | |
385 WebIDBCallbacks* callbacks) { | |
386 ResetCursorPrefetchCaches(); | |
387 IndexedDBHostMsg_DatabaseOpenCursor_Params params; | |
388 init_params(params, callbacks); | |
389 params.ipc_database_id = ipc_database_id; | |
390 params.transaction_id = transaction_id; | |
391 params.object_store_id = object_store_id; | |
392 params.index_id = index_id; | |
393 params.key_range = IndexedDBKeyRange(key_range); | |
394 params.direction = direction; | |
395 params.key_only = key_only; | |
396 params.task_type = task_type; | |
397 Send(new IndexedDBHostMsg_DatabaseOpenCursor(params)); | |
398 } | |
399 | |
400 void IndexedDBDispatcher::RequestIDBDatabaseCount( | |
401 int32 ipc_database_id, | |
402 int64 transaction_id, | |
403 int64 object_store_id, | |
404 int64 index_id, | |
405 const IndexedDBKeyRange& key_range, | |
406 WebKit::WebIDBCallbacks* callbacks) { | |
407 ResetCursorPrefetchCaches(); | |
408 IndexedDBHostMsg_DatabaseCount_Params params; | |
409 init_params(params, callbacks); | |
410 params.ipc_database_id = ipc_database_id; | |
411 params.transaction_id = transaction_id; | |
412 params.object_store_id = object_store_id; | |
413 params.index_id = index_id; | |
414 params.key_range = IndexedDBKeyRange(key_range); | |
415 Send(new IndexedDBHostMsg_DatabaseCount(params)); | |
416 } | |
417 | |
418 void IndexedDBDispatcher::RequestIDBDatabaseDeleteRange( | |
419 int32 ipc_database_id, | |
420 int64 transaction_id, | |
421 int64 object_store_id, | |
422 const IndexedDBKeyRange& key_range, | |
423 WebKit::WebIDBCallbacks* callbacks) { | |
424 ResetCursorPrefetchCaches(); | |
425 IndexedDBHostMsg_DatabaseDeleteRange_Params params; | |
426 init_params(params, callbacks); | |
427 params.ipc_database_id = ipc_database_id; | |
428 params.transaction_id = transaction_id; | |
429 params.object_store_id = object_store_id; | |
430 params.key_range = key_range; | |
431 Send(new IndexedDBHostMsg_DatabaseDeleteRange(params)); | |
432 } | |
433 | |
434 void IndexedDBDispatcher::RequestIDBDatabaseClear( | |
435 int32 ipc_database_id, | |
436 int64 transaction_id, | |
437 int64 object_store_id, | |
438 WebKit::WebIDBCallbacks* callbacks_ptr) { | |
439 scoped_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
440 int32 ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
441 Send(new IndexedDBHostMsg_DatabaseClear(CurrentWorkerId(), | |
442 ipc_callbacks_id, | |
443 ipc_database_id, | |
444 transaction_id, | |
445 object_store_id)); | |
446 } | |
447 | |
448 void IndexedDBDispatcher::CursorDestroyed(int32 ipc_cursor_id) { | |
449 cursors_.erase(ipc_cursor_id); | |
450 } | |
451 | |
452 void IndexedDBDispatcher::DatabaseDestroyed(int32 ipc_database_id) { | |
453 DCHECK_EQ(databases_.count(ipc_database_id), 1u); | |
454 databases_.erase(ipc_database_id); | |
455 } | |
456 | |
457 void IndexedDBDispatcher::OnSuccessIDBDatabase( | |
458 int32 ipc_thread_id, | |
459 int32 ipc_callbacks_id, | |
460 int32 ipc_database_callbacks_id, | |
461 int32 ipc_object_id, | |
462 const IndexedDBDatabaseMetadata& idb_metadata) { | |
463 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
464 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
465 if (!callbacks) | |
466 return; | |
467 WebIDBMetadata metadata(ConvertMetadata(idb_metadata)); | |
468 // If an upgrade was performed, count will be non-zero. | |
469 if (!databases_.count(ipc_object_id)) | |
470 databases_[ipc_object_id] = new RendererWebIDBDatabaseImpl( | |
471 ipc_object_id, ipc_database_callbacks_id); | |
472 DCHECK_EQ(databases_.count(ipc_object_id), 1u); | |
473 callbacks->onSuccess(databases_[ipc_object_id], metadata); | |
474 pending_callbacks_.Remove(ipc_callbacks_id); | |
475 } | |
476 | |
477 void IndexedDBDispatcher::OnSuccessIndexedDBKey(int32 ipc_thread_id, | |
478 int32 ipc_callbacks_id, | |
479 const IndexedDBKey& key) { | |
480 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
481 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
482 if (!callbacks) | |
483 return; | |
484 callbacks->onSuccess(WebIDBKey(key)); | |
485 pending_callbacks_.Remove(ipc_callbacks_id); | |
486 } | |
487 | |
488 void IndexedDBDispatcher::OnSuccessStringList( | |
489 int32 ipc_thread_id, | |
490 int32 ipc_callbacks_id, | |
491 const std::vector<string16>& value) { | |
492 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
493 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
494 if (!callbacks) | |
495 return; | |
496 callbacks->onSuccess(WebVector<WebString>(value)); | |
497 pending_callbacks_.Remove(ipc_callbacks_id); | |
498 } | |
499 | |
500 void IndexedDBDispatcher::OnSuccessValue(int32 ipc_thread_id, | |
501 int32 ipc_callbacks_id, | |
502 const std::vector<char>& value) { | |
503 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
504 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
505 if (!callbacks) | |
506 return; | |
507 WebData web_value; | |
508 if (value.size()) | |
509 web_value.assign(&value.front(), value.size()); | |
510 callbacks->onSuccess(web_value); | |
511 pending_callbacks_.Remove(ipc_callbacks_id); | |
512 } | |
513 | |
514 void IndexedDBDispatcher::OnSuccessValueWithKey( | |
515 int32 ipc_thread_id, | |
516 int32 ipc_callbacks_id, | |
517 const std::vector<char>& value, | |
518 const IndexedDBKey& primary_key, | |
519 const IndexedDBKeyPath& key_path) { | |
520 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
521 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
522 if (!callbacks) | |
523 return; | |
524 WebData web_value; | |
525 if (value.size()) | |
526 web_value.assign(&value.front(), value.size()); | |
527 callbacks->onSuccess(web_value, primary_key, key_path); | |
528 pending_callbacks_.Remove(ipc_callbacks_id); | |
529 } | |
530 | |
531 void IndexedDBDispatcher::OnSuccessInteger(int32 ipc_thread_id, | |
532 int32 ipc_callbacks_id, | |
533 int64 value) { | |
534 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
535 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
536 if (!callbacks) | |
537 return; | |
538 callbacks->onSuccess(value); | |
539 pending_callbacks_.Remove(ipc_callbacks_id); | |
540 } | |
541 | |
542 void IndexedDBDispatcher::OnSuccessUndefined(int32 ipc_thread_id, | |
543 int32 ipc_callbacks_id) { | |
544 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
545 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
546 if (!callbacks) | |
547 return; | |
548 callbacks->onSuccess(); | |
549 pending_callbacks_.Remove(ipc_callbacks_id); | |
550 } | |
551 | |
552 void IndexedDBDispatcher::OnSuccessOpenCursor( | |
553 const IndexedDBMsg_CallbacksSuccessIDBCursor_Params& p) { | |
554 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | |
555 int32 ipc_callbacks_id = p.ipc_callbacks_id; | |
556 int32 ipc_object_id = p.ipc_cursor_id; | |
557 const IndexedDBKey& key = p.key; | |
558 const IndexedDBKey& primary_key = p.primary_key; | |
559 WebData web_value; | |
560 if (p.value.size()) | |
561 web_value.assign(&p.value.front(), p.value.size()); | |
562 | |
563 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
564 if (!callbacks) | |
565 return; | |
566 | |
567 RendererWebIDBCursorImpl* cursor = | |
568 new RendererWebIDBCursorImpl(ipc_object_id); | |
569 cursors_[ipc_object_id] = cursor; | |
570 callbacks->onSuccess(cursor, key, primary_key, web_value); | |
571 | |
572 pending_callbacks_.Remove(ipc_callbacks_id); | |
573 } | |
574 | |
575 void IndexedDBDispatcher::OnSuccessCursorContinue( | |
576 const IndexedDBMsg_CallbacksSuccessCursorContinue_Params& p) { | |
577 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | |
578 int32 ipc_callbacks_id = p.ipc_callbacks_id; | |
579 int32 ipc_cursor_id = p.ipc_cursor_id; | |
580 const IndexedDBKey& key = p.key; | |
581 const IndexedDBKey& primary_key = p.primary_key; | |
582 const std::vector<char>& value = p.value; | |
583 | |
584 RendererWebIDBCursorImpl* cursor = cursors_[ipc_cursor_id]; | |
585 DCHECK(cursor); | |
586 | |
587 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
588 if (!callbacks) | |
589 return; | |
590 | |
591 WebData web_value; | |
592 if (value.size()) | |
593 web_value.assign(&value.front(), value.size()); | |
594 callbacks->onSuccess(key, primary_key, web_value); | |
595 | |
596 pending_callbacks_.Remove(ipc_callbacks_id); | |
597 } | |
598 | |
599 void IndexedDBDispatcher::OnSuccessCursorPrefetch( | |
600 const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params& p) { | |
601 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | |
602 int32 ipc_callbacks_id = p.ipc_callbacks_id; | |
603 int32 ipc_cursor_id = p.ipc_cursor_id; | |
604 const std::vector<IndexedDBKey>& keys = p.keys; | |
605 const std::vector<IndexedDBKey>& primary_keys = p.primary_keys; | |
606 std::vector<WebData> values(p.values.size()); | |
607 for (size_t i = 0; i < p.values.size(); ++i) { | |
608 if (p.values[i].size()) | |
609 values[i].assign(&p.values[i].front(), p.values[i].size()); | |
610 } | |
611 RendererWebIDBCursorImpl* cursor = cursors_[ipc_cursor_id]; | |
612 DCHECK(cursor); | |
613 cursor->SetPrefetchData(keys, primary_keys, values); | |
614 | |
615 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
616 DCHECK(callbacks); | |
617 cursor->CachedContinue(callbacks); | |
618 pending_callbacks_.Remove(ipc_callbacks_id); | |
619 } | |
620 | |
621 void IndexedDBDispatcher::OnIntBlocked(int32 ipc_thread_id, | |
622 int32 ipc_callbacks_id, | |
623 int64 existing_version) { | |
624 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
625 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
626 DCHECK(callbacks); | |
627 callbacks->onBlocked(existing_version); | |
628 } | |
629 | |
630 void IndexedDBDispatcher::OnUpgradeNeeded( | |
631 const IndexedDBMsg_CallbacksUpgradeNeeded_Params& p) { | |
632 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | |
633 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(p.ipc_callbacks_id); | |
634 DCHECK(callbacks); | |
635 WebIDBMetadata metadata(ConvertMetadata(p.idb_metadata)); | |
636 DCHECK(!databases_.count(p.ipc_database_id)); | |
637 databases_[p.ipc_database_id] = new RendererWebIDBDatabaseImpl( | |
638 p.ipc_database_id, p.ipc_database_callbacks_id); | |
639 callbacks->onUpgradeNeeded( | |
640 p.old_version, databases_[p.ipc_database_id], metadata); | |
641 } | |
642 | |
643 void IndexedDBDispatcher::OnError(int32 ipc_thread_id, | |
644 int32 ipc_callbacks_id, | |
645 int code, | |
646 const string16& message) { | |
647 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
648 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
649 if (!callbacks) | |
650 return; | |
651 callbacks->onError(WebIDBDatabaseError(code, message)); | |
652 pending_callbacks_.Remove(ipc_callbacks_id); | |
653 } | |
654 | |
655 void IndexedDBDispatcher::OnAbort(int32 ipc_thread_id, | |
656 int32 ipc_database_callbacks_id, | |
657 int64 transaction_id, | |
658 int code, | |
659 const string16& message) { | |
660 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
661 WebIDBDatabaseCallbacks* callbacks = | |
662 pending_database_callbacks_.Lookup(ipc_database_callbacks_id); | |
663 if (!callbacks) | |
664 return; | |
665 callbacks->onAbort(transaction_id, WebIDBDatabaseError(code, message)); | |
666 } | |
667 | |
668 void IndexedDBDispatcher::OnComplete(int32 ipc_thread_id, | |
669 int32 ipc_database_callbacks_id, | |
670 int64 transaction_id) { | |
671 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
672 WebIDBDatabaseCallbacks* callbacks = | |
673 pending_database_callbacks_.Lookup(ipc_database_callbacks_id); | |
674 if (!callbacks) | |
675 return; | |
676 callbacks->onComplete(transaction_id); | |
677 } | |
678 | |
679 void IndexedDBDispatcher::OnForcedClose(int32 ipc_thread_id, | |
680 int32 ipc_database_callbacks_id) { | |
681 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
682 WebIDBDatabaseCallbacks* callbacks = | |
683 pending_database_callbacks_.Lookup(ipc_database_callbacks_id); | |
684 if (!callbacks) | |
685 return; | |
686 callbacks->onForcedClose(); | |
687 } | |
688 | |
689 void IndexedDBDispatcher::OnIntVersionChange(int32 ipc_thread_id, | |
690 int32 ipc_database_callbacks_id, | |
691 int64 old_version, | |
692 int64 new_version) { | |
693 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
694 WebIDBDatabaseCallbacks* callbacks = | |
695 pending_database_callbacks_.Lookup(ipc_database_callbacks_id); | |
696 // callbacks would be NULL if a versionchange event is received after close | |
697 // has been called. | |
698 if (!callbacks) | |
699 return; | |
700 callbacks->onVersionChange(old_version, new_version); | |
701 } | |
702 | |
703 void IndexedDBDispatcher::ResetCursorPrefetchCaches( | |
704 int32 ipc_exception_cursor_id) { | |
705 typedef std::map<int32, RendererWebIDBCursorImpl*>::iterator Iterator; | |
706 for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) { | |
707 if (i->first == ipc_exception_cursor_id) | |
708 continue; | |
709 i->second->ResetPrefetchCache(); | |
710 } | |
711 } | |
712 | |
713 } // namespace content | |
OLD | NEW |