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

Side by Side Diff: content/browser/indexed_db/database_impl.cc

Issue 2727733004: [IndexedDB] Closing mojo connections when renderer quits (Closed)
Patch Set: No more raw pointers where we're not guarenteed lifetime Created 3 years, 9 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/database_impl.h" 5 #include "content/browser/indexed_db/database_impl.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/sequenced_task_runner.h"
8 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
9 #include "content/browser/bad_message.h" 10 #include "content/browser/bad_message.h"
10 #include "content/browser/child_process_security_policy_impl.h" 11 #include "content/browser/child_process_security_policy_impl.h"
11 #include "content/browser/indexed_db/indexed_db_connection.h" 12 #include "content/browser/indexed_db/indexed_db_connection.h"
12 #include "content/browser/indexed_db/indexed_db_context_impl.h" 13 #include "content/browser/indexed_db/indexed_db_context_impl.h"
13 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" 14 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
14 #include "content/browser/indexed_db/indexed_db_transaction.h" 15 #include "content/browser/indexed_db/indexed_db_transaction.h"
15 #include "content/browser/indexed_db/indexed_db_value.h" 16 #include "content/browser/indexed_db/indexed_db_value.h"
16 #include "storage/browser/blob/blob_storage_context.h" 17 #include "storage/browser/blob/blob_storage_context.h"
17 #include "storage/browser/quota/quota_manager_proxy.h" 18 #include "storage/browser/quota/quota_manager_proxy.h"
18 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" 19 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h"
19 20
20 using std::swap; 21 using std::swap;
21 22
22 namespace content { 23 namespace content {
23 24
24 namespace { 25 namespace {
25 const char kInvalidBlobUuid[] = "Blob UUID is invalid"; 26 const char kInvalidBlobUuid[] = "Blob UUID is invalid";
26 const char kInvalidBlobFilePath[] = "Blob file path is invalid"; 27 const char kInvalidBlobFilePath[] = "Blob file path is invalid";
27 } // namespace 28 } // namespace
28 29
30 // Expect to be created on IO thread, and called/destroyed on IDB thread.
29 class DatabaseImpl::IDBThreadHelper { 31 class DatabaseImpl::IDBThreadHelper {
30 public: 32 public:
31 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection, 33 IDBThreadHelper(std::unique_ptr<IndexedDBConnection> connection,
32 const url::Origin& origin, 34 const url::Origin& origin,
33 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host); 35 scoped_refptr<IndexedDBContextImpl> indexed_db_context);
34 ~IDBThreadHelper(); 36 ~IDBThreadHelper();
35 37
38 void ConnectionOpened();
39
36 void CreateObjectStore(int64_t transaction_id, 40 void CreateObjectStore(int64_t transaction_id,
37 int64_t object_store_id, 41 int64_t object_store_id,
38 const base::string16& name, 42 const base::string16& name,
39 const IndexedDBKeyPath& key_path, 43 const IndexedDBKeyPath& key_path,
40 bool auto_increment); 44 bool auto_increment);
41 void DeleteObjectStore(int64_t transaction_id, int64_t object_store_id); 45 void DeleteObjectStore(int64_t transaction_id, int64_t object_store_id);
42 void RenameObjectStore(int64_t transaction_id, 46 void RenameObjectStore(int64_t transaction_id,
43 int64_t object_store_id, 47 int64_t object_store_id,
44 const base::string16& new_name); 48 const base::string16& new_name);
45 void CreateTransaction(int64_t transaction_id, 49 void CreateTransaction(int64_t transaction_id,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 const base::string16& new_name); 123 const base::string16& new_name);
120 void Abort(int64_t transaction_id); 124 void Abort(int64_t transaction_id);
121 void Commit(int64_t transaction_id); 125 void Commit(int64_t transaction_id);
122 void OnGotUsageAndQuotaForCommit(int64_t transaction_id, 126 void OnGotUsageAndQuotaForCommit(int64_t transaction_id,
123 storage::QuotaStatusCode status, 127 storage::QuotaStatusCode status,
124 int64_t usage, 128 int64_t usage,
125 int64_t quota); 129 int64_t quota);
126 void AckReceivedBlobs(const std::vector<std::string>& uuids); 130 void AckReceivedBlobs(const std::vector<std::string>& uuids);
127 131
128 private: 132 private:
129 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host_; 133 scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
130 std::unique_ptr<IndexedDBConnection> connection_; 134 std::unique_ptr<IndexedDBConnection> connection_;
131 const url::Origin origin_; 135 const url::Origin origin_;
132 base::WeakPtrFactory<IDBThreadHelper> weak_factory_; 136 base::WeakPtrFactory<IDBThreadHelper> weak_factory_;
133 }; 137 };
134 138
135 DatabaseImpl::DatabaseImpl( 139 DatabaseImpl::DatabaseImpl(std::unique_ptr<IndexedDBConnection> connection,
136 std::unique_ptr<IndexedDBConnection> connection, 140 const url::Origin& origin,
137 const url::Origin& origin, 141 IndexedDBDispatcherHost* dispatcher_host,
138 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) 142 scoped_refptr<base::SequencedTaskRunner> idb_runner)
139 : dispatcher_host_(dispatcher_host), 143 : dispatcher_host_(dispatcher_host),
140 origin_(origin), 144 origin_(origin),
141 idb_runner_(base::ThreadTaskRunnerHandle::Get()) { 145 idb_runner_(std::move(idb_runner)) {
146 DCHECK(connection);
142 helper_ = new IDBThreadHelper(std::move(connection), origin, 147 helper_ = new IDBThreadHelper(std::move(connection), origin,
143 std::move(dispatcher_host)); 148 dispatcher_host->context());
149 idb_runner_->PostTask(FROM_HERE,
150 base::Bind(&IDBThreadHelper::ConnectionOpened,
151 base::Unretained(helper_)));
144 } 152 }
145 153
146 DatabaseImpl::~DatabaseImpl() { 154 DatabaseImpl::~DatabaseImpl() {
147 idb_runner_->DeleteSoon(FROM_HERE, helper_); 155 idb_runner_->DeleteSoon(FROM_HERE, helper_);
148 } 156 }
149 157
150 void DatabaseImpl::CreateObjectStore(int64_t transaction_id, 158 void DatabaseImpl::CreateObjectStore(int64_t transaction_id,
151 int64_t object_store_id, 159 int64_t object_store_id,
152 const base::string16& name, 160 const base::string16& name,
153 const IndexedDBKeyPath& key_path, 161 const IndexedDBKeyPath& key_path,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 base::Unretained(helper_), observers)); 223 base::Unretained(helper_), observers));
216 } 224 }
217 225
218 void DatabaseImpl::Get( 226 void DatabaseImpl::Get(
219 int64_t transaction_id, 227 int64_t transaction_id,
220 int64_t object_store_id, 228 int64_t object_store_id,
221 int64_t index_id, 229 int64_t index_id,
222 const IndexedDBKeyRange& key_range, 230 const IndexedDBKeyRange& key_range,
223 bool key_only, 231 bool key_only,
224 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 232 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
225 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 233 scoped_refptr<IndexedDBCallbacks> callbacks(
226 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 234 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
235 std::move(callbacks_info), idb_runner_));
227 idb_runner_->PostTask( 236 idb_runner_->PostTask(
228 FROM_HERE, base::Bind(&IDBThreadHelper::Get, base::Unretained(helper_), 237 FROM_HERE, base::Bind(&IDBThreadHelper::Get, base::Unretained(helper_),
229 transaction_id, object_store_id, index_id, 238 transaction_id, object_store_id, index_id,
230 key_range, key_only, base::Passed(&callbacks))); 239 key_range, key_only, base::Passed(&callbacks)));
231 } 240 }
232 241
233 void DatabaseImpl::GetAll( 242 void DatabaseImpl::GetAll(
234 int64_t transaction_id, 243 int64_t transaction_id,
235 int64_t object_store_id, 244 int64_t object_store_id,
236 int64_t index_id, 245 int64_t index_id,
237 const IndexedDBKeyRange& key_range, 246 const IndexedDBKeyRange& key_range,
238 bool key_only, 247 bool key_only,
239 int64_t max_count, 248 int64_t max_count,
240 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 249 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
241 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 250 scoped_refptr<IndexedDBCallbacks> callbacks(
242 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 251 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
252 std::move(callbacks_info), idb_runner_));
243 idb_runner_->PostTask( 253 idb_runner_->PostTask(
244 FROM_HERE, 254 FROM_HERE,
245 base::Bind(&IDBThreadHelper::GetAll, base::Unretained(helper_), 255 base::Bind(&IDBThreadHelper::GetAll, base::Unretained(helper_),
246 transaction_id, object_store_id, index_id, key_range, key_only, 256 transaction_id, object_store_id, index_id, key_range, key_only,
247 max_count, base::Passed(&callbacks))); 257 max_count, base::Passed(&callbacks)));
248 } 258 }
249 259
250 void DatabaseImpl::Put( 260 void DatabaseImpl::Put(
251 int64_t transaction_id, 261 int64_t transaction_id,
252 int64_t object_store_id, 262 int64_t object_store_id,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 info->file->name, info->mime_type); 294 info->file->name, info->mime_type);
285 if (info->size != -1) { 295 if (info->size != -1) {
286 blob_info[i].set_last_modified(info->file->last_modified); 296 blob_info[i].set_last_modified(info->file->last_modified);
287 blob_info[i].set_size(info->size); 297 blob_info[i].set_size(info->size);
288 } 298 }
289 } else { 299 } else {
290 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size); 300 blob_info[i] = IndexedDBBlobInfo(info->uuid, info->mime_type, info->size);
291 } 301 }
292 } 302 }
293 303
294 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 304 scoped_refptr<IndexedDBCallbacks> callbacks(
295 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 305 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
306 std::move(callbacks_info), idb_runner_));
296 307
297 idb_runner_->PostTask( 308 idb_runner_->PostTask(
298 FROM_HERE, 309 FROM_HERE,
299 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_), 310 base::Bind(&IDBThreadHelper::Put, base::Unretained(helper_),
300 transaction_id, object_store_id, base::Passed(&value), 311 transaction_id, object_store_id, base::Passed(&value),
301 base::Passed(&handles), base::Passed(&blob_info), key, mode, 312 base::Passed(&handles), base::Passed(&blob_info), key, mode,
302 index_keys, base::Passed(&callbacks))); 313 index_keys, base::Passed(&callbacks)));
303 } 314 }
304 315
305 void DatabaseImpl::SetIndexKeys( 316 void DatabaseImpl::SetIndexKeys(
(...skipping 18 matching lines...) Expand all
324 335
325 void DatabaseImpl::OpenCursor( 336 void DatabaseImpl::OpenCursor(
326 int64_t transaction_id, 337 int64_t transaction_id,
327 int64_t object_store_id, 338 int64_t object_store_id,
328 int64_t index_id, 339 int64_t index_id,
329 const IndexedDBKeyRange& key_range, 340 const IndexedDBKeyRange& key_range,
330 blink::WebIDBCursorDirection direction, 341 blink::WebIDBCursorDirection direction,
331 bool key_only, 342 bool key_only,
332 blink::WebIDBTaskType task_type, 343 blink::WebIDBTaskType task_type,
333 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 344 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
334 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 345 scoped_refptr<IndexedDBCallbacks> callbacks(
335 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 346 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
347 std::move(callbacks_info), idb_runner_));
336 idb_runner_->PostTask( 348 idb_runner_->PostTask(
337 FROM_HERE, 349 FROM_HERE,
338 base::Bind(&IDBThreadHelper::OpenCursor, base::Unretained(helper_), 350 base::Bind(&IDBThreadHelper::OpenCursor, base::Unretained(helper_),
339 transaction_id, object_store_id, index_id, key_range, 351 transaction_id, object_store_id, index_id, key_range,
340 direction, key_only, task_type, base::Passed(&callbacks))); 352 direction, key_only, task_type, base::Passed(&callbacks)));
341 } 353 }
342 354
343 void DatabaseImpl::Count( 355 void DatabaseImpl::Count(
344 int64_t transaction_id, 356 int64_t transaction_id,
345 int64_t object_store_id, 357 int64_t object_store_id,
346 int64_t index_id, 358 int64_t index_id,
347 const IndexedDBKeyRange& key_range, 359 const IndexedDBKeyRange& key_range,
348 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 360 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
349 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 361 scoped_refptr<IndexedDBCallbacks> callbacks(
350 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 362 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
363 std::move(callbacks_info), idb_runner_));
351 idb_runner_->PostTask( 364 idb_runner_->PostTask(
352 FROM_HERE, base::Bind(&IDBThreadHelper::Count, base::Unretained(helper_), 365 FROM_HERE, base::Bind(&IDBThreadHelper::Count, base::Unretained(helper_),
353 transaction_id, object_store_id, index_id, 366 transaction_id, object_store_id, index_id,
354 key_range, base::Passed(&callbacks))); 367 key_range, base::Passed(&callbacks)));
355 } 368 }
356 369
357 void DatabaseImpl::DeleteRange( 370 void DatabaseImpl::DeleteRange(
358 int64_t transaction_id, 371 int64_t transaction_id,
359 int64_t object_store_id, 372 int64_t object_store_id,
360 const IndexedDBKeyRange& key_range, 373 const IndexedDBKeyRange& key_range,
361 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 374 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
362 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 375 scoped_refptr<IndexedDBCallbacks> callbacks(
363 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 376 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
377 std::move(callbacks_info), idb_runner_));
364 idb_runner_->PostTask( 378 idb_runner_->PostTask(
365 FROM_HERE, 379 FROM_HERE,
366 base::Bind(&IDBThreadHelper::DeleteRange, base::Unretained(helper_), 380 base::Bind(&IDBThreadHelper::DeleteRange, base::Unretained(helper_),
367 transaction_id, object_store_id, key_range, 381 transaction_id, object_store_id, key_range,
368 base::Passed(&callbacks))); 382 base::Passed(&callbacks)));
369 } 383 }
370 384
371 void DatabaseImpl::Clear( 385 void DatabaseImpl::Clear(
372 int64_t transaction_id, 386 int64_t transaction_id,
373 int64_t object_store_id, 387 int64_t object_store_id,
374 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) { 388 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info) {
375 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( 389 scoped_refptr<IndexedDBCallbacks> callbacks(
376 dispatcher_host_.get(), origin_, std::move(callbacks_info))); 390 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
391 std::move(callbacks_info), idb_runner_));
377 idb_runner_->PostTask( 392 idb_runner_->PostTask(
378 FROM_HERE, 393 FROM_HERE,
379 base::Bind(&IDBThreadHelper::Clear, base::Unretained(helper_), 394 base::Bind(&IDBThreadHelper::Clear, base::Unretained(helper_),
380 transaction_id, object_store_id, base::Passed(&callbacks))); 395 transaction_id, object_store_id, base::Passed(&callbacks)));
381 } 396 }
382 397
383 void DatabaseImpl::CreateIndex(int64_t transaction_id, 398 void DatabaseImpl::CreateIndex(int64_t transaction_id,
384 int64_t object_store_id, 399 int64_t object_store_id,
385 int64_t index_id, 400 int64_t index_id,
386 const base::string16& name, 401 const base::string16& name,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 } 441 }
427 442
428 void DatabaseImpl::AckReceivedBlobs(const std::vector<std::string>& uuids) { 443 void DatabaseImpl::AckReceivedBlobs(const std::vector<std::string>& uuids) {
429 for (const auto& uuid : uuids) 444 for (const auto& uuid : uuids)
430 dispatcher_host_->DropBlobData(uuid); 445 dispatcher_host_->DropBlobData(uuid);
431 } 446 }
432 447
433 DatabaseImpl::IDBThreadHelper::IDBThreadHelper( 448 DatabaseImpl::IDBThreadHelper::IDBThreadHelper(
434 std::unique_ptr<IndexedDBConnection> connection, 449 std::unique_ptr<IndexedDBConnection> connection,
435 const url::Origin& origin, 450 const url::Origin& origin,
436 scoped_refptr<IndexedDBDispatcherHost> dispatcher_host) 451 scoped_refptr<IndexedDBContextImpl> indexed_db_context)
437 : dispatcher_host_(std::move(dispatcher_host)), 452 : indexed_db_context_(indexed_db_context),
438 connection_(std::move(connection)), 453 connection_(std::move(connection)),
439 origin_(origin), 454 origin_(origin),
440 weak_factory_(this) { 455 weak_factory_(this) {}
441 dispatcher_host_->context()->ConnectionOpened(origin_, connection.get()); 456
457 DatabaseImpl::IDBThreadHelper::~IDBThreadHelper() {
458 LOG(ERROR) << "in destructor";
459 LOG(ERROR) << "object " << connection_.get();
460 LOG(ERROR) << "connected: " << connection_->IsConnected();
461 if (connection_->IsConnected())
462 connection_->Close();
463 LOG(ERROR) << "about to call closed";
Reilly Grant (use Gerrit) 2017/03/11 00:31:40 Leftover logging.
dmurph 2017/03/29 18:40:24 Done.
464 indexed_db_context_->ConnectionClosed(origin_, connection_.get());
442 } 465 }
443 466
444 DatabaseImpl::IDBThreadHelper::~IDBThreadHelper() { 467 void DatabaseImpl::IDBThreadHelper::ConnectionOpened() {
445 if (connection_->IsConnected()) 468 indexed_db_context_->ConnectionOpened(origin_, connection_.get());
446 connection_->Close();
447 dispatcher_host_->context()->ConnectionClosed(origin_, connection_.get());
448 } 469 }
449 470
450 void DatabaseImpl::IDBThreadHelper::CreateObjectStore( 471 void DatabaseImpl::IDBThreadHelper::CreateObjectStore(
451 int64_t transaction_id, 472 int64_t transaction_id,
452 int64_t object_store_id, 473 int64_t object_store_id,
453 const base::string16& name, 474 const base::string16& name,
454 const IndexedDBKeyPath& key_path, 475 const IndexedDBKeyPath& key_path,
455 bool auto_increment) { 476 bool auto_increment) {
456 if (!connection_->IsConnected()) 477 if (!connection_->IsConnected())
457 return; 478 return;
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 connection_->GetTransaction(transaction_id); 821 connection_->GetTransaction(transaction_id);
801 if (!transaction) 822 if (!transaction)
802 return; 823 return;
803 824
804 // Always allow empty or delete-only transactions. 825 // Always allow empty or delete-only transactions.
805 if (transaction->size() == 0) { 826 if (transaction->size() == 0) {
806 connection_->database()->Commit(transaction); 827 connection_->database()->Commit(transaction);
807 return; 828 return;
808 } 829 }
809 830
810 dispatcher_host_->context()->quota_manager_proxy()->GetUsageAndQuota( 831 indexed_db_context_->quota_manager_proxy()->GetUsageAndQuota(
811 dispatcher_host_->context()->TaskRunner(), origin_.GetURL(), 832 indexed_db_context_->TaskRunner(), origin_.GetURL(),
812 storage::kStorageTypeTemporary, 833 storage::kStorageTypeTemporary,
813 base::Bind(&IDBThreadHelper::OnGotUsageAndQuotaForCommit, 834 base::Bind(&IDBThreadHelper::OnGotUsageAndQuotaForCommit,
814 weak_factory_.GetWeakPtr(), transaction_id)); 835 weak_factory_.GetWeakPtr(), transaction_id));
815 } 836 }
816 837
817 void DatabaseImpl::IDBThreadHelper::OnGotUsageAndQuotaForCommit( 838 void DatabaseImpl::IDBThreadHelper::OnGotUsageAndQuotaForCommit(
818 int64_t transaction_id, 839 int64_t transaction_id,
819 storage::QuotaStatusCode status, 840 storage::QuotaStatusCode status,
820 int64_t usage, 841 int64_t usage,
821 int64_t quota) { 842 int64_t quota) {
(...skipping 10 matching lines...) Expand all
832 usage + transaction->size() <= quota) { 853 usage + transaction->size() <= quota) {
833 connection_->database()->Commit(transaction); 854 connection_->database()->Commit(transaction);
834 } else { 855 } else {
835 connection_->AbortTransaction( 856 connection_->AbortTransaction(
836 transaction, 857 transaction,
837 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); 858 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
838 } 859 }
839 } 860 }
840 861
841 } // namespace content 862 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698