OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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/indexed_db/database_impl.h" | |
6 | |
7 #include "content/browser/bad_message.h" | |
8 #include "content/browser/child_process_security_policy_impl.h" | |
9 #include "content/browser/indexed_db/indexed_db_connection.h" | |
10 #include "content/browser/indexed_db/indexed_db_context_impl.h" | |
11 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" | |
12 #include "content/browser/indexed_db/indexed_db_value.h" | |
13 #include "content/common/indexed_db/indexed_db_messages.h" | |
14 #include "storage/browser/blob/blob_storage_context.h" | |
15 #include "storage/browser/quota/quota_manager_proxy.h" | |
16 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" | |
17 | |
18 namespace content { | |
19 | |
20 namespace { | |
21 const char kInvalidBlobUuid[] = "Blob UUID is invalid"; | |
22 } // namespace | |
23 | |
24 class DatabaseImpl::IDBThreadHelper { | |
25 public: | |
26 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection, | |
27 const url::Origin& origin, | |
28 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); | |
29 ~IDBThreadHelper(); | |
30 | |
31 void CreateObjectStore(int64_t transaction_id, | |
32 int64_t object_store_id, | |
33 const base::string16& name, | |
34 const IndexedDBKeyPath& key_path, | |
35 bool auto_increment); | |
36 void DeleteObjectStore(int64_t transaction_id, int64_t object_store_id); | |
37 void RenameObjectStore(int64_t transaction_id, | |
38 int64_t object_store_id, | |
39 const base::string16& new_name); | |
40 void CreateTransaction(int64_t transaction_id, | |
41 const std::vector<int64_t>& object_store_ids, | |
42 blink::WebIDBTransactionMode mode); | |
43 void Close(); | |
44 void VersionChangeIgnored(); | |
45 void AddObserver(int64_t transaction_id, | |
46 int32_t observer_id, | |
47 bool include_transaction, | |
48 bool no_records, | |
49 bool values, | |
50 uint16_t operation_types); | |
51 void RemoveObservers(const std::vector<int32_t>& observers); | |
52 void Get(int64_t transaction_id, | |
53 int64_t object_store_id, | |
54 int64_t index_id, | |
55 const IndexedDBKeyRange& key_range, | |
56 bool key_only, | |
57 scoped_refptr<IndexedDBCallbacks> callbacks); | |
58 void GetAll(int64_t transaction_id, | |
59 int64_t object_store_id, | |
60 int64_t index_id, | |
61 const IndexedDBKeyRange& key_range, | |
62 bool key_only, | |
63 int64_t max_count, | |
64 scoped_refptr<IndexedDBCallbacks> callbacks); | |
65 void Put(int64_t transaction_id, | |
66 int64_t object_store_id, | |
67 ::indexed_db::mojom::ValuePtr value, | |
68 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles, | |
69 const IndexedDBKey& key, | |
70 blink::WebIDBPutMode mode, | |
71 const std::vector<IndexedDBIndexKeys>& index_keys, | |
72 scoped_refptr<IndexedDBCallbacks> callbacks); | |
73 void SetIndexKeys(int64_t transaction_id, | |
74 int64_t object_store_id, | |
75 const IndexedDBKey& primary_key, | |
76 const std::vector<IndexedDBIndexKeys>& index_keys); | |
77 void SetIndexesReady(int64_t transaction_id, | |
78 int64_t object_store_id, | |
79 const std::vector<int64_t>& index_ids); | |
80 void OpenCursor(int64_t transaction_id, | |
81 int64_t object_store_id, | |
82 int64_t index_id, | |
83 const IndexedDBKeyRange& key_range, | |
84 blink::WebIDBCursorDirection direction, | |
85 bool key_only, | |
86 blink::WebIDBTaskType task_type, | |
87 scoped_refptr<IndexedDBCallbacks> callbacks); | |
88 void Count(int64_t transaction_id, | |
89 int64_t object_store_id, | |
90 int64_t index_id, | |
91 const IndexedDBKeyRange& key_range, | |
92 scoped_refptr<IndexedDBCallbacks> callbacks); | |
93 void DeleteRange(int64_t transaction_id, | |
94 int64_t object_store_id, | |
95 const IndexedDBKeyRange& key_range, | |
96 scoped_refptr<IndexedDBCallbacks> callbacks); | |
97 void Clear(int64_t transaction_id, | |
98 int64_t object_store_id, | |
99 scoped_refptr<IndexedDBCallbacks> callbacks); | |
100 void CreateIndex(int64_t transaction_id, | |
101 int64_t object_store_id, | |
102 int64_t index_id, | |
103 const base::string16& name, | |
104 const IndexedDBKeyPath& key_path, | |
105 bool unique, | |
106 bool multi_entry); | |
107 void DeleteIndex(int64_t transaction_id, | |
108 int64_t object_store_id, | |
109 int64_t index_id); | |
110 void RenameIndex(int64_t transaction_id, | |
111 int64_t object_store_id, | |
112 int64_t index_id, | |
113 const base::string16& new_name); | |
114 void Abort(int64_t transaction_id); | |
115 void Commit(int64_t transaction_id); | |
116 void OnGotUsageAndQuotaForCommit(int64_t transaction_id, | |
117 storage::QuotaStatusCode status, | |
118 int64_t usage, | |
119 int64_t quota); | |
120 void AckReceivedBlobs(const std::vector<std::string>& uuids); | |
121 | |
122 private: | |
123 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_; | |
124 std::unique_ptr<IndexedDBConnection> connection_; | |
125 const url::Origin origin_; | |
126 base::WeakPtrFactory<IDBThreadHelper> weak_factory_; | |
127 }; | |
128 | |
129 DatabaseImpl::DatabaseImpl( | |
130 std::unique_ptr<IndexedDBConnection> connection, | |
131 const url::Origin& origin, | |
132 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) | |
133 : dispatcher_host_(dispatcher_host), | |
134 origin_(origin), | |
135 idb_runner_(base::ThreadTaskRunnerHandle::Get()) { | |
136 helper_ = new IDBThreadHelper(std::move(connection), origin, | |
137 std::move(dispatcher_host)); | |
138 } | |
139 | |
140 DatabaseImpl::~DatabaseImpl() { | |
141 idb_runner_->DeleteSoon(FROM_HERE, helper_); | |
142 } | |
143 | |
144 void DatabaseImpl::CreateObjectStore(int64_t transaction_id, | |
145 int64_t object_store_id, | |
146 const base::string16& name, | |
147 const IndexedDBKeyPath& key_path, | |
148 bool auto_increment) { | |
149 idb_runner_->PostTask( | |
150 FROM_HERE, base::Bind(&IDBThreadHelper::CreateObjectStore, | |
151 base::Unretained(helper_), transaction_id, | |
152 object_store_id, name, key_path, auto_increment)); | |
153 } | |
154 | |
155 void DatabaseImpl::DeleteObjectStore(int64_t transaction_id, | |
156 int64_t object_store_id) { | |
157 idb_runner_->PostTask( | |
158 FROM_HERE, | |
159 base::Bind(&IDBThreadHelper::DeleteObjectStore, base::Unretained(helper_), | |
160 transaction_id, object_store_id)); | |
161 } | |
162 | |
163 void DatabaseImpl::RenameObjectStore(int64_t transaction_id, | |
164 int64_t object_store_id, | |
165 const base::string16& new_name) { | |
166 idb_runner_->PostTask( | |
167 FROM_HERE, | |
168 base::Bind(&IDBThreadHelper::RenameObjectStore, base::Unretained(helper_), | |
169 transaction_id, object_store_id, new_name)); | |
170 } | |
171 | |
172 void DatabaseImpl::CreateTransaction( | |
173 int64_t transaction_id, | |
174 const std::vector<int64_t>& object_store_ids, | |
175 blink::WebIDBTransactionMode mode) { | |
176 idb_runner_->PostTask( | |
177 FROM_HERE, | |
178 base::Bind(&IDBThreadHelper::CreateTransaction, base::Unretained(helper_), | |
179 transaction_id, object_store_ids, mode)); | |
180 } | |
181 | |
182 void DatabaseImpl::Close() { | |
183 idb_runner_->PostTask(FROM_HERE, base::Bind(&IDBThreadHelper::Close, | |
184 base::Unretained(helper_))); | |
185 } | |
186 | |
187 void DatabaseImpl::VersionChangeIgnored() { | |
188 idb_runner_->PostTask(FROM_HERE, | |
189 base::Bind(&IDBThreadHelper::VersionChangeIgnored, | |
190 base::Unretained(helper_))); | |
191 } | |
192 | |
193 void DatabaseImpl::AddObserver(int64_t transaction_id, | |
194 int32_t observer_id, | |
195 bool include_transaction, | |
196 bool no_records, | |
197 bool values, | |
198 uint16_t operation_types) { | |
199 idb_runner_->PostTask( | |
200 FROM_HERE, | |
201 base::Bind(&IDBThreadHelper::AddObserver, base::Unretained(helper_), | |
202 transaction_id, observer_id, include_transaction, no_records, | |
203 values, operation_types)); | |
204 } | |
205 | |
206 void DatabaseImpl::RemoveObservers(const std::vector<int32_t>& observers) { | |
207 idb_runner_->PostTask(FROM_HERE, | |
208 base::Bind(&IDBThreadHelper::RemoveObservers, | |
209 base::Unretained(helper_), observers)); | |
210 } | |
211 | |
212 void DatabaseImpl::Get( | |
213 int64_t transaction_id, | |
214 int64_t object_store_id, | |
215 int64_t index_id, | |
216 const IndexedDBKeyRange& key_range, | |
217 bool key_only, | |
218 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
219 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
220 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
221 idb_runner_->PostTask( | |
222 FROM_HERE, base::Bind(&IDBThreadHelper::Get, base::Unretained(helper_), | |
223 transaction_id, object_store_id, index_id, | |
224 key_range, key_only, base::Passed(&callbacks))); | |
225 } | |
226 | |
227 void DatabaseImpl::GetAll( | |
228 int64_t transaction_id, | |
229 int64_t object_store_id, | |
230 int64_t index_id, | |
231 const IndexedDBKeyRange& key_range, | |
232 bool key_only, | |
233 int64_t max_count, | |
234 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
235 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
236 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
237 idb_runner_->PostTask( | |
238 FROM_HERE, | |
239 base::Bind(&IDBThreadHelper::GetAll, base::Unretained(helper_), | |
240 transaction_id, object_store_id, index_id, key_range, key_only, | |
241 max_count, base::Passed(&callbacks))); | |
242 } | |
243 | |
244 void DatabaseImpl::Put( | |
245 int64_t transaction_id, | |
246 int64_t object_store_id, | |
247 ::indexed_db::mojom::ValuePtr value, | |
248 const IndexedDBKey& key, | |
249 blink::WebIDBPutMode mode, | |
250 const std::vector<IndexedDBIndexKeys>& index_keys, | |
251 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
252 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | |
253 for (const auto& info : value->blob_or_file_info) { | |
254 std::unique_ptr<storage::BlobDataHandle> handle = | |
255 dispatcher_host_->blob_storage_context()->GetBlobDataFromUUID( | |
256 info->uuid); | |
257 if (!handle) { | |
258 mojo::ReportBadMessage(kInvalidBlobUuid); | |
259 return; | |
260 } | |
261 handles.push_back(std::move(handle)); | |
262 } | |
263 | |
264 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
265 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
266 | |
267 idb_runner_->PostTask( | |
268 FROM_HERE, base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), | |
269 transaction_id, object_store_id, | |
270 base::Passed(&value), base::Passed(&handles), key, | |
271 mode, index_keys, base::Passed(&callbacks))); | |
272 } | |
273 | |
274 void DatabaseImpl::SetIndexKeys( | |
275 int64_t transaction_id, | |
276 int64_t object_store_id, | |
277 const IndexedDBKey& primary_key, | |
278 const std::vector<IndexedDBIndexKeys>& index_keys) { | |
279 idb_runner_->PostTask( | |
280 FROM_HERE, | |
281 base::Bind(&IDBThreadHelper::SetIndexKeys, base::Unretained(helper_), | |
282 transaction_id, object_store_id, primary_key, index_keys)); | |
283 } | |
284 | |
285 void DatabaseImpl::SetIndexesReady(int64_t transaction_id, | |
286 int64_t object_store_id, | |
287 const std::vector<int64_t>& index_ids) { | |
288 idb_runner_->PostTask( | |
289 FROM_HERE, | |
290 base::Bind(&IDBThreadHelper::SetIndexesReady, base::Unretained(helper_), | |
291 transaction_id, object_store_id, index_ids)); | |
292 } | |
293 | |
294 void DatabaseImpl::OpenCursor( | |
295 int64_t transaction_id, | |
296 int64_t object_store_id, | |
297 int64_t index_id, | |
298 const IndexedDBKeyRange& key_range, | |
299 blink::WebIDBCursorDirection direction, | |
300 bool key_only, | |
301 blink::WebIDBTaskType task_type, | |
302 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
303 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
304 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
305 idb_runner_->PostTask( | |
306 FROM_HERE, | |
307 base::Bind(&IDBThreadHelper::OpenCursor, base::Unretained(helper_), | |
308 transaction_id, object_store_id, index_id, key_range, | |
309 direction, key_only, task_type, base::Passed(&callbacks))); | |
310 } | |
311 | |
312 void DatabaseImpl::Count( | |
313 int64_t transaction_id, | |
314 int64_t object_store_id, | |
315 int64_t index_id, | |
316 const IndexedDBKeyRange& key_range, | |
317 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
318 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
319 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
320 idb_runner_->PostTask( | |
321 FROM_HERE, base::Bind(&IDBThreadHelper::Count, base::Unretained(helper_), | |
322 transaction_id, object_store_id, index_id, | |
323 key_range, base::Passed(&callbacks))); | |
324 } | |
325 | |
326 void DatabaseImpl::DeleteRange( | |
327 int64_t transaction_id, | |
328 int64_t object_store_id, | |
329 const IndexedDBKeyRange& key_range, | |
330 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
331 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
332 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
333 idb_runner_->PostTask( | |
334 FROM_HERE, | |
335 base::Bind(&IDBThreadHelper::DeleteRange, base::Unretained(helper_), | |
336 transaction_id, object_store_id, key_range, | |
337 base::Passed(&callbacks))); | |
338 } | |
339 | |
340 void DatabaseImpl::Clear( | |
341 int64_t transaction_id, | |
342 int64_t object_store_id, | |
343 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { | |
344 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( | |
345 dispatcher_host_.get(), origin_, std::move(callbacks_info))); | |
346 idb_runner_->PostTask( | |
347 FROM_HERE, | |
348 base::Bind(&IDBThreadHelper::Clear, base::Unretained(helper_), | |
349 transaction_id, object_store_id, base::Passed(&callbacks))); | |
350 } | |
351 | |
352 void DatabaseImpl::CreateIndex(int64_t transaction_id, | |
353 int64_t object_store_id, | |
354 int64_t index_id, | |
355 const base::string16& name, | |
356 const IndexedDBKeyPath& key_path, | |
357 bool unique, | |
358 bool multi_entry) { | |
359 idb_runner_->PostTask( | |
360 FROM_HERE, | |
361 base::Bind(&IDBThreadHelper::CreateIndex, base::Unretained(helper_), | |
362 transaction_id, object_store_id, index_id, name, key_path, | |
363 unique, multi_entry)); | |
364 } | |
365 | |
366 void DatabaseImpl::DeleteIndex(int64_t transaction_id, | |
367 int64_t object_store_id, | |
368 int64_t index_id) { | |
369 idb_runner_->PostTask( | |
370 FROM_HERE, | |
371 base::Bind(&IDBThreadHelper::DeleteIndex, base::Unretained(helper_), | |
372 transaction_id, object_store_id, index_id)); | |
373 } | |
374 | |
375 void DatabaseImpl::RenameIndex(int64_t transaction_id, | |
376 int64_t object_store_id, | |
377 int64_t index_id, | |
378 const base::string16& new_name) { | |
379 idb_runner_->PostTask( | |
380 FROM_HERE, | |
381 base::Bind(&IDBThreadHelper::RenameIndex, base::Unretained(helper_), | |
382 transaction_id, object_store_id, index_id, new_name)); | |
383 } | |
384 | |
385 void DatabaseImpl::Abort(int64_t transaction_id) { | |
386 idb_runner_->PostTask( | |
387 FROM_HERE, base::Bind(&IDBThreadHelper::Abort, base::Unretained(helper_), | |
388 transaction_id)); | |
389 } | |
390 | |
391 void DatabaseImpl::Commit(int64_t transaction_id) { | |
392 idb_runner_->PostTask( | |
393 FROM_HERE, base::Bind(&IDBThreadHelper::Commit, base::Unretained(helper_), | |
394 transaction_id)); | |
395 } | |
396 | |
397 void DatabaseImpl::AckReceivedBlobs(const std::vector<std::string>& uuids) { | |
398 for (const auto& uuid : uuids) | |
399 dispatcher_host_->DropBlobData(uuid); | |
400 } | |
401 | |
402 DatabaseImpl::IDBThreadHelper::IDBThreadHelper( | |
403 std::unique_ptr<IndexedDBConnection> connection, | |
404 const url::Origin& origin, | |
405 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) | |
406 : dispatcher_host_(std::move(dispatcher_host)), | |
407 connection_(std::move(connection)), | |
408 origin_(origin), | |
409 weak_factory_(this) { | |
410 dispatcher_host_->context()->ConnectionOpened(origin_, connection.get()); | |
411 } | |
412 | |
413 DatabaseImpl::IDBThreadHelper::~IDBThreadHelper() { | |
414 if (connection_->IsConnected()) | |
415 connection_->Close(); | |
416 dispatcher_host_->context()->ConnectionClosed(origin_, connection_.get()); | |
417 } | |
418 | |
419 void DatabaseImpl::IDBThreadHelper::CreateObjectStore( | |
420 int64_t transaction_id, | |
421 int64_t object_store_id, | |
422 const base::string16& name, | |
423 const IndexedDBKeyPath& key_path, | |
424 bool auto_increment) { | |
425 if (!connection_->IsConnected()) | |
426 return; | |
427 | |
428 connection_->database()->CreateObjectStore( | |
429 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
430 name, key_path, auto_increment); | |
431 } | |
432 | |
433 void DatabaseImpl::IDBThreadHelper::DeleteObjectStore(int64_t transaction_id, | |
434 int64_t object_store_id) { | |
435 if (!connection_->IsConnected()) | |
436 return; | |
437 | |
438 connection_->database()->DeleteObjectStore( | |
439 dispatcher_host_->HostTransactionId(transaction_id), object_store_id); | |
440 } | |
441 | |
442 void DatabaseImpl::IDBThreadHelper::RenameObjectStore( | |
443 int64_t transaction_id, | |
444 int64_t object_store_id, | |
445 const base::string16& new_name) { | |
446 if (!connection_->IsConnected()) | |
447 return; | |
448 | |
449 connection_->database()->RenameObjectStore( | |
450 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
451 new_name); | |
452 } | |
453 | |
454 void DatabaseImpl::IDBThreadHelper::CreateTransaction( | |
455 int64_t transaction_id, | |
456 const std::vector<int64_t>& object_store_ids, | |
457 blink::WebIDBTransactionMode mode) { | |
458 if (!connection_->IsConnected()) | |
459 return; | |
460 | |
461 int64_t host_transaction_id = | |
462 dispatcher_host_->HostTransactionId(transaction_id); | |
463 if (!dispatcher_host_->RegisterTransactionId(host_transaction_id, origin_)) { | |
464 DLOG(ERROR) << "Duplicate host_transaction_id."; | |
465 return; | |
466 } | |
467 | |
468 connection_->database()->CreateTransaction( | |
469 host_transaction_id, connection_.get(), object_store_ids, mode); | |
470 } | |
471 | |
472 void DatabaseImpl::IDBThreadHelper::Close() { | |
473 if (!connection_->IsConnected()) | |
474 return; | |
475 | |
476 connection_->Close(); | |
477 } | |
478 | |
479 void DatabaseImpl::IDBThreadHelper::VersionChangeIgnored() { | |
480 if (!connection_->IsConnected()) | |
481 return; | |
482 | |
483 connection_->VersionChangeIgnored(); | |
484 } | |
485 | |
486 void DatabaseImpl::IDBThreadHelper::AddObserver(int64_t transaction_id, | |
487 int32_t observer_id, | |
488 bool include_transaction, | |
489 bool no_records, | |
490 bool values, | |
491 uint16_t operation_types) { | |
492 if (!connection_->IsConnected()) | |
493 return; | |
494 | |
495 IndexedDBObserver::Options options(include_transaction, no_records, values, | |
496 operation_types); | |
497 connection_->database()->AddPendingObserver( | |
498 dispatcher_host_->HostTransactionId(transaction_id), observer_id, | |
499 options); | |
500 } | |
501 | |
502 void DatabaseImpl::IDBThreadHelper::RemoveObservers( | |
503 const std::vector<int32_t>& observers) { | |
504 if (!connection_->IsConnected()) | |
505 return; | |
506 | |
507 connection_->RemoveObservers(observers); | |
508 } | |
509 | |
510 void DatabaseImpl::IDBThreadHelper::Get( | |
511 int64_t transaction_id, | |
512 int64_t object_store_id, | |
513 int64_t index_id, | |
514 const IndexedDBKeyRange& key_range, | |
515 bool key_only, | |
516 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
517 if (!connection_->IsConnected()) | |
518 return; | |
519 | |
520 connection_->database()->Get( | |
521 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
522 index_id, base::MakeUnique<IndexedDBKeyRange>(key_range), key_only, | |
523 callbacks); | |
524 } | |
525 | |
526 void DatabaseImpl::IDBThreadHelper::GetAll( | |
527 int64_t transaction_id, | |
528 int64_t object_store_id, | |
529 int64_t index_id, | |
530 const IndexedDBKeyRange& key_range, | |
531 bool key_only, | |
532 int64_t max_count, | |
533 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
534 if (!connection_->IsConnected()) | |
535 return; | |
536 | |
537 connection_->database()->GetAll( | |
538 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
539 index_id, base::MakeUnique<IndexedDBKeyRange>(key_range), key_only, | |
540 max_count, callbacks); | |
541 } | |
542 | |
543 void DatabaseImpl::IDBThreadHelper::Put( | |
544 int64_t transaction_id, | |
545 int64_t object_store_id, | |
546 ::indexed_db::mojom::ValuePtr mojo_value, | |
547 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles, | |
548 const IndexedDBKey& key, | |
549 blink::WebIDBPutMode mode, | |
550 const std::vector<IndexedDBIndexKeys>& index_keys, | |
551 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
552 if (!connection_->IsConnected()) | |
553 return; | |
554 | |
555 int64_t host_transaction_id = | |
556 dispatcher_host_->HostTransactionId(transaction_id); | |
557 | |
558 ChildProcessSecurityPolicyImpl* policy = | |
559 ChildProcessSecurityPolicyImpl::GetInstance(); | |
560 std::vector<IndexedDBBlobInfo> blob_info( | |
561 mojo_value->blob_or_file_info.size()); | |
562 for (size_t i = 0; i < mojo_value->blob_or_file_info.size(); ++i) { | |
563 const auto& info = mojo_value->blob_or_file_info[i]; | |
564 if (info->file) { | |
565 if (!info->file->path.empty()) { | |
566 if (!policy->CanReadFile(dispatcher_host_->ipc_process_id(), | |
567 info->file->path)) { | |
568 bad_message::ReceivedBadMessage(dispatcher_host_.get(), | |
569 bad_message::IDBDH_CAN_READ_FILE); | |
570 return; | |
571 } | |
572 } | |
573 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->file->path, | |
574 info->file->name, info->mime_type); | |
575 if (info->size != static_cast<uint64_t>(-1)) { | |
576 blob_info[i].set_last_modified(info->file->last_modified); | |
577 blob_info[i].set_size(info->size); | |
578 } | |
579 } else { | |
580 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); | |
581 } | |
582 } | |
583 | |
584 uint64_t commit_size = mojo_value->bits.size(); | |
585 IndexedDBValue value; | |
586 value.bits = std::move(mojo_value->bits); | |
587 value.blob_info.swap(blob_info); | |
588 connection_->database()->Put(host_transaction_id, object_store_id, &value, | |
589 &handles, base::MakeUnique<IndexedDBKey>(key), | |
590 mode, callbacks, index_keys); | |
591 | |
592 // Size can't be big enough to overflow because it represents the | |
593 // actual bytes passed through IPC. | |
594 dispatcher_host_->AddToTransaction(host_transaction_id, commit_size); | |
595 } | |
596 | |
597 void DatabaseImpl::IDBThreadHelper::SetIndexKeys( | |
598 int64_t transaction_id, | |
599 int64_t object_store_id, | |
600 const IndexedDBKey& primary_key, | |
601 const std::vector<IndexedDBIndexKeys>& index_keys) { | |
602 if (!connection_->IsConnected()) | |
603 return; | |
604 | |
605 connection_->database()->SetIndexKeys( | |
606 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
607 base::MakeUnique<IndexedDBKey>(primary_key), index_keys); | |
608 } | |
609 | |
610 void DatabaseImpl::IDBThreadHelper::SetIndexesReady( | |
611 int64_t transaction_id, | |
612 int64_t object_store_id, | |
613 const std::vector<int64_t>& index_ids) { | |
614 if (!connection_->IsConnected()) | |
615 return; | |
616 | |
617 connection_->database()->SetIndexesReady( | |
618 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
619 index_ids); | |
620 } | |
621 | |
622 void DatabaseImpl::IDBThreadHelper::OpenCursor( | |
623 int64_t transaction_id, | |
624 int64_t object_store_id, | |
625 int64_t index_id, | |
626 const IndexedDBKeyRange& key_range, | |
627 blink::WebIDBCursorDirection direction, | |
628 bool key_only, | |
629 blink::WebIDBTaskType task_type, | |
630 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
631 if (!connection_->IsConnected()) | |
632 return; | |
633 | |
634 connection_->database()->OpenCursor( | |
635 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
636 index_id, base::MakeUnique<IndexedDBKeyRange>(key_range), direction, | |
637 key_only, task_type, callbacks); | |
dcheng
2016/11/04 21:37:46
Nit: std::move(callbacks) here and elsewhere?
Reilly Grant (use Gerrit)
2016/11/04 22:02:54
Done.
| |
638 } | |
639 | |
640 void DatabaseImpl::IDBThreadHelper::Count( | |
641 int64_t transaction_id, | |
642 int64_t object_store_id, | |
643 int64_t index_id, | |
644 const IndexedDBKeyRange& key_range, | |
645 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
646 if (!connection_->IsConnected()) | |
647 return; | |
648 | |
649 connection_->database()->Count( | |
650 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
651 index_id, base::MakeUnique<IndexedDBKeyRange>(key_range), callbacks); | |
652 } | |
653 | |
654 void DatabaseImpl::IDBThreadHelper::DeleteRange( | |
655 int64_t transaction_id, | |
656 int64_t object_store_id, | |
657 const IndexedDBKeyRange& key_range, | |
658 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
659 if (!connection_->IsConnected()) | |
660 return; | |
661 | |
662 connection_->database()->DeleteRange( | |
663 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
664 base::MakeUnique<IndexedDBKeyRange>(key_range), callbacks); | |
665 } | |
666 | |
667 void DatabaseImpl::IDBThreadHelper::Clear( | |
668 int64_t transaction_id, | |
669 int64_t object_store_id, | |
670 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
671 if (!connection_->IsConnected()) | |
672 return; | |
673 | |
674 connection_->database()->Clear( | |
675 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
676 callbacks); | |
677 } | |
678 | |
679 void DatabaseImpl::IDBThreadHelper::CreateIndex( | |
680 int64_t transaction_id, | |
681 int64_t object_store_id, | |
682 int64_t index_id, | |
683 const base::string16& name, | |
684 const IndexedDBKeyPath& key_path, | |
685 bool unique, | |
686 bool multi_entry) { | |
687 if (!connection_->IsConnected()) | |
688 return; | |
689 | |
690 connection_->database()->CreateIndex( | |
691 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
692 index_id, name, key_path, unique, multi_entry); | |
693 } | |
694 | |
695 void DatabaseImpl::IDBThreadHelper::DeleteIndex(int64_t transaction_id, | |
696 int64_t object_store_id, | |
697 int64_t index_id) { | |
698 if (!connection_->IsConnected()) | |
699 return; | |
700 | |
701 connection_->database()->DeleteIndex( | |
702 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
703 index_id); | |
704 } | |
705 | |
706 void DatabaseImpl::IDBThreadHelper::RenameIndex( | |
707 int64_t transaction_id, | |
708 int64_t object_store_id, | |
709 int64_t index_id, | |
710 const base::string16& new_name) { | |
711 if (!connection_->IsConnected()) | |
712 return; | |
713 | |
714 connection_->database()->RenameIndex( | |
715 dispatcher_host_->HostTransactionId(transaction_id), object_store_id, | |
716 index_id, new_name); | |
717 } | |
718 | |
719 void DatabaseImpl::IDBThreadHelper::Abort(int64_t transaction_id) { | |
720 if (!connection_->IsConnected()) | |
721 return; | |
722 | |
723 connection_->database()->Abort( | |
724 dispatcher_host_->HostTransactionId(transaction_id)); | |
725 } | |
726 | |
727 void DatabaseImpl::IDBThreadHelper::Commit(int64_t transaction_id) { | |
728 if (!connection_->IsConnected()) | |
729 return; | |
730 | |
731 int64_t host_transaction_id = | |
732 dispatcher_host_->HostTransactionId(transaction_id); | |
733 // May have been aborted by back end before front-end could request commit. | |
734 int64_t transaction_size; | |
735 if (!dispatcher_host_->GetTransactionSize(host_transaction_id, | |
736 &transaction_size)) | |
737 return; | |
738 | |
739 // Always allow empty or delete-only transactions. | |
740 if (transaction_size == 0) { | |
741 connection_->database()->Commit(host_transaction_id); | |
742 return; | |
743 } | |
744 | |
745 dispatcher_host_->context()->quota_manager_proxy()->GetUsageAndQuota( | |
746 dispatcher_host_->context()->TaskRunner(), origin_.GetURL(), | |
747 storage::kStorageTypeTemporary, | |
748 base::Bind(&IDBThreadHelper::OnGotUsageAndQuotaForCommit, | |
749 weak_factory_.GetWeakPtr(), transaction_id)); | |
750 } | |
751 | |
752 void DatabaseImpl::IDBThreadHelper::OnGotUsageAndQuotaForCommit( | |
753 int64_t transaction_id, | |
754 storage::QuotaStatusCode status, | |
755 int64_t usage, | |
756 int64_t quota) { | |
757 // May have disconnected while quota check was pending. | |
758 if (!connection_->IsConnected()) | |
759 return; | |
760 | |
761 int64_t host_transaction_id = | |
762 dispatcher_host_->HostTransactionId(transaction_id); | |
763 // May have aborted while quota check was pending. | |
764 int64_t transaction_size; | |
765 if (!dispatcher_host_->GetTransactionSize(host_transaction_id, | |
766 &transaction_size)) | |
767 return; | |
768 | |
769 if (status == storage::kQuotaStatusOk && usage + transaction_size <= quota) { | |
770 connection_->database()->Commit(host_transaction_id); | |
771 } else { | |
772 connection_->database()->Abort( | |
773 host_transaction_id, | |
774 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); | |
775 } | |
776 } | |
777 | |
778 } // namespace content | |
OLD | NEW |