OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/indexed_db_dispatcher_host.h" | 5 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" | 40 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" |
41 #include "url/origin.h" | 41 #include "url/origin.h" |
42 | 42 |
43 using storage::DatabaseUtil; | 43 using storage::DatabaseUtil; |
44 using blink::WebIDBKey; | 44 using blink::WebIDBKey; |
45 | 45 |
46 namespace content { | 46 namespace content { |
47 | 47 |
48 namespace { | 48 namespace { |
49 | 49 |
| 50 const char* kInvalidOrigin = "Origin is invalid"; |
| 51 |
50 bool IsValidOrigin(const url::Origin& origin) { | 52 bool IsValidOrigin(const url::Origin& origin) { |
51 return !origin.unique(); | 53 return !origin.unique(); |
52 } | 54 } |
53 | 55 |
54 } // namespace | 56 } // namespace |
55 | 57 |
56 IndexedDBDispatcherHost::IndexedDBDispatcherHost( | 58 IndexedDBDispatcherHost::IndexedDBDispatcherHost( |
57 int ipc_process_id, | 59 int ipc_process_id, |
58 net::URLRequestContextGetter* request_context_getter, | 60 net::URLRequestContextGetter* request_context_getter, |
59 IndexedDBContextImpl* indexed_db_context, | 61 IndexedDBContextImpl* indexed_db_context, |
60 ChromeBlobStorageContext* blob_storage_context) | 62 ChromeBlobStorageContext* blob_storage_context) |
61 : BrowserMessageFilter(IndexedDBMsgStart), | 63 : BrowserMessageFilter(IndexedDBMsgStart), |
| 64 BrowserAssociatedInterface(this, this), |
62 request_context_getter_(request_context_getter), | 65 request_context_getter_(request_context_getter), |
63 indexed_db_context_(indexed_db_context), | 66 indexed_db_context_(indexed_db_context), |
64 blob_storage_context_(blob_storage_context), | 67 blob_storage_context_(blob_storage_context), |
65 database_dispatcher_host_(base::MakeUnique<DatabaseDispatcherHost>(this)), | 68 database_dispatcher_host_(base::MakeUnique<DatabaseDispatcherHost>(this)), |
66 cursor_dispatcher_host_(base::MakeUnique<CursorDispatcherHost>(this)), | 69 cursor_dispatcher_host_(base::MakeUnique<CursorDispatcherHost>(this)), |
67 ipc_process_id_(ipc_process_id) { | 70 ipc_process_id_(ipc_process_id) { |
68 DCHECK(indexed_db_context_.get()); | 71 DCHECK(indexed_db_context_.get()); |
69 } | 72 } |
70 | 73 |
71 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {} | 74 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {} |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread() || | 127 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread() || |
125 (message.type() == IndexedDBHostMsg_DatabasePut::ID || | 128 (message.type() == IndexedDBHostMsg_DatabasePut::ID || |
126 message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID)); | 129 message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID)); |
127 | 130 |
128 bool handled = database_dispatcher_host_->OnMessageReceived(message) || | 131 bool handled = database_dispatcher_host_->OnMessageReceived(message) || |
129 cursor_dispatcher_host_->OnMessageReceived(message); | 132 cursor_dispatcher_host_->OnMessageReceived(message); |
130 | 133 |
131 if (!handled) { | 134 if (!handled) { |
132 handled = true; | 135 handled = true; |
133 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcherHost, message) | 136 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcherHost, message) |
134 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryGetDatabaseNames, | |
135 OnIDBFactoryGetDatabaseNames) | |
136 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryOpen, OnIDBFactoryOpen) | |
137 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryDeleteDatabase, | |
138 OnIDBFactoryDeleteDatabase) | |
139 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_AckReceivedBlobs, OnAckReceivedBlobs) | 137 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_AckReceivedBlobs, OnAckReceivedBlobs) |
140 IPC_MESSAGE_UNHANDLED(handled = false) | 138 IPC_MESSAGE_UNHANDLED(handled = false) |
141 IPC_END_MESSAGE_MAP() | 139 IPC_END_MESSAGE_MAP() |
142 } | 140 } |
143 return handled; | 141 return handled; |
144 } | 142 } |
145 | 143 |
146 int32_t IndexedDBDispatcherHost::Add(IndexedDBCursor* cursor) { | 144 int32_t IndexedDBDispatcherHost::Add(IndexedDBCursor* cursor) { |
147 if (!cursor_dispatcher_host_) { | 145 if (!cursor_dispatcher_host_) { |
148 return 0; | 146 return 0; |
149 } | 147 } |
150 return cursor_dispatcher_host_->map_.Add(cursor); | 148 return cursor_dispatcher_host_->map_.Add(cursor); |
151 } | 149 } |
152 | 150 |
153 int32_t IndexedDBDispatcherHost::Add(IndexedDBConnection* connection, | 151 int32_t IndexedDBDispatcherHost::Add(IndexedDBConnection* connection, |
154 int32_t ipc_thread_id, | |
155 const url::Origin& origin) { | 152 const url::Origin& origin) { |
156 if (!database_dispatcher_host_) { | 153 if (!database_dispatcher_host_) { |
157 connection->Close(); | 154 connection->Close(); |
158 delete connection; | 155 delete connection; |
159 return -1; | 156 return -1; |
160 } | 157 } |
161 int32_t ipc_database_id = database_dispatcher_host_->map_.Add(connection); | 158 int32_t ipc_database_id = database_dispatcher_host_->map_.Add(connection); |
162 connection->set_id(ipc_database_id); | 159 connection->set_id(ipc_database_id); |
163 context()->ConnectionOpened(origin, connection); | 160 context()->ConnectionOpened(origin, connection); |
164 database_dispatcher_host_->database_origin_map_[ipc_database_id] = origin; | 161 database_dispatcher_host_->database_origin_map_[ipc_database_id] = origin; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 else | 244 else |
248 --iter->second.second; | 245 --iter->second.second; |
249 } | 246 } |
250 | 247 |
251 IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId( | 248 IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId( |
252 int32_t ipc_cursor_id) { | 249 int32_t ipc_cursor_id) { |
253 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); | 250 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); |
254 return cursor_dispatcher_host_->map_.Lookup(ipc_cursor_id); | 251 return cursor_dispatcher_host_->map_.Lookup(ipc_cursor_id); |
255 } | 252 } |
256 | 253 |
257 ::IndexedDBDatabaseMetadata IndexedDBDispatcherHost::ConvertMetadata( | |
258 const content::IndexedDBDatabaseMetadata& web_metadata) { | |
259 ::IndexedDBDatabaseMetadata metadata; | |
260 metadata.id = web_metadata.id; | |
261 metadata.name = web_metadata.name; | |
262 metadata.version = web_metadata.version; | |
263 metadata.max_object_store_id = web_metadata.max_object_store_id; | |
264 | |
265 for (const auto& iter : web_metadata.object_stores) { | |
266 const content::IndexedDBObjectStoreMetadata& web_store_metadata = | |
267 iter.second; | |
268 ::IndexedDBObjectStoreMetadata idb_store_metadata; | |
269 idb_store_metadata.id = web_store_metadata.id; | |
270 idb_store_metadata.name = web_store_metadata.name; | |
271 idb_store_metadata.key_path = web_store_metadata.key_path; | |
272 idb_store_metadata.auto_increment = web_store_metadata.auto_increment; | |
273 idb_store_metadata.max_index_id = web_store_metadata.max_index_id; | |
274 | |
275 for (const auto& index_iter : web_store_metadata.indexes) { | |
276 const content::IndexedDBIndexMetadata& web_index_metadata = | |
277 index_iter.second; | |
278 ::IndexedDBIndexMetadata idb_index_metadata; | |
279 idb_index_metadata.id = web_index_metadata.id; | |
280 idb_index_metadata.name = web_index_metadata.name; | |
281 idb_index_metadata.key_path = web_index_metadata.key_path; | |
282 idb_index_metadata.unique = web_index_metadata.unique; | |
283 idb_index_metadata.multi_entry = web_index_metadata.multi_entry; | |
284 idb_store_metadata.indexes.push_back(idb_index_metadata); | |
285 } | |
286 metadata.object_stores.push_back(idb_store_metadata); | |
287 } | |
288 return metadata; | |
289 } | |
290 | |
291 IndexedDBMsg_ObserverChanges IndexedDBDispatcherHost::ConvertObserverChanges( | 254 IndexedDBMsg_ObserverChanges IndexedDBDispatcherHost::ConvertObserverChanges( |
292 std::unique_ptr<IndexedDBObserverChanges> changes) { | 255 std::unique_ptr<IndexedDBObserverChanges> changes) { |
293 IndexedDBMsg_ObserverChanges idb_changes; | 256 IndexedDBMsg_ObserverChanges idb_changes; |
294 idb_changes.observation_index = changes->release_observation_indices_map(); | 257 idb_changes.observation_index = changes->release_observation_indices_map(); |
295 for (const auto& observation : changes->release_observations()) | 258 for (const auto& observation : changes->release_observations()) |
296 idb_changes.observations.push_back(ConvertObservation(observation.get())); | 259 idb_changes.observations.push_back(ConvertObservation(observation.get())); |
297 return idb_changes; | 260 return idb_changes; |
298 } | 261 } |
299 | 262 |
300 IndexedDBMsg_Observation IndexedDBDispatcherHost::ConvertObservation( | 263 IndexedDBMsg_Observation IndexedDBDispatcherHost::ConvertObservation( |
301 const IndexedDBObservation* observation) { | 264 const IndexedDBObservation* observation) { |
302 // TODO(palakj): Modify function for indexed_db_value. Issue crbug.com/609934. | 265 // TODO(palakj): Modify function for indexed_db_value. Issue crbug.com/609934. |
303 IndexedDBMsg_Observation idb_observation; | 266 IndexedDBMsg_Observation idb_observation; |
304 idb_observation.object_store_id = observation->object_store_id(); | 267 idb_observation.object_store_id = observation->object_store_id(); |
305 idb_observation.type = observation->type(); | 268 idb_observation.type = observation->type(); |
306 idb_observation.key_range = observation->key_range(); | 269 idb_observation.key_range = observation->key_range(); |
307 return idb_observation; | 270 return idb_observation; |
308 } | 271 } |
309 | 272 |
310 void IndexedDBDispatcherHost::OnIDBFactoryGetDatabaseNames( | 273 void IndexedDBDispatcherHost::GetDatabaseNames( |
311 const IndexedDBHostMsg_FactoryGetDatabaseNames_Params& params) { | 274 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, |
312 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); | 275 const url::Origin& origin) { |
| 276 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
313 | 277 |
314 if (!IsValidOrigin(params.origin)) { | 278 if (!IsValidOrigin(origin)) { |
315 bad_message::ReceivedBadMessage(this, bad_message::IDBDH_INVALID_ORIGIN); | 279 mojo::ReportBadMessage(kInvalidOrigin); |
316 return; | 280 return; |
317 } | 281 } |
318 | 282 |
| 283 scoped_refptr<IndexedDBCallbacks> callbacks( |
| 284 new IndexedDBCallbacks(this, origin, std::move(callbacks_info))); |
| 285 indexed_db_context_->TaskRunner()->PostTask( |
| 286 FROM_HERE, |
| 287 base::Bind(&IndexedDBDispatcherHost::GetDatabaseNamesOnIDBThread, this, |
| 288 callbacks, origin)); |
| 289 } |
| 290 |
| 291 void IndexedDBDispatcherHost::Open( |
| 292 int32_t worker_thread, |
| 293 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, |
| 294 ::indexed_db::mojom::DatabaseCallbacksAssociatedPtrInfo |
| 295 database_callbacks_info, |
| 296 const url::Origin& origin, |
| 297 const base::string16& name, |
| 298 int64_t version, |
| 299 int64_t transaction_id) { |
| 300 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 301 |
| 302 if (!IsValidOrigin(origin)) { |
| 303 mojo::ReportBadMessage(kInvalidOrigin); |
| 304 return; |
| 305 } |
| 306 |
| 307 scoped_refptr<IndexedDBCallbacks> callbacks( |
| 308 new IndexedDBCallbacks(this, origin, std::move(callbacks_info))); |
| 309 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks( |
| 310 new IndexedDBDatabaseCallbacks(this, worker_thread, |
| 311 std::move(database_callbacks_info))); |
| 312 indexed_db_context_->TaskRunner()->PostTask( |
| 313 FROM_HERE, |
| 314 base::Bind(&IndexedDBDispatcherHost::OpenOnIDBThread, this, callbacks, |
| 315 database_callbacks, origin, name, version, transaction_id)); |
| 316 } |
| 317 |
| 318 void IndexedDBDispatcherHost::DeleteDatabase( |
| 319 ::indexed_db::mojom::CallbacksAssociatedPtrInfo callbacks_info, |
| 320 const url::Origin& origin, |
| 321 const base::string16& name) { |
| 322 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 323 |
| 324 if (!IsValidOrigin(origin)) { |
| 325 mojo::ReportBadMessage(kInvalidOrigin); |
| 326 return; |
| 327 } |
| 328 |
| 329 scoped_refptr<IndexedDBCallbacks> callbacks( |
| 330 new IndexedDBCallbacks(this, origin, std::move(callbacks_info))); |
| 331 indexed_db_context_->TaskRunner()->PostTask( |
| 332 FROM_HERE, base::Bind(&IndexedDBDispatcherHost::DeleteDatabaseOnIDBThread, |
| 333 this, callbacks, origin, name)); |
| 334 } |
| 335 |
| 336 void IndexedDBDispatcherHost::GetDatabaseNamesOnIDBThread( |
| 337 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 338 const url::Origin& origin) { |
| 339 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); |
| 340 |
319 base::FilePath indexed_db_path = indexed_db_context_->data_path(); | 341 base::FilePath indexed_db_path = indexed_db_context_->data_path(); |
320 context()->GetIDBFactory()->GetDatabaseNames( | 342 context()->GetIDBFactory()->GetDatabaseNames( |
321 new IndexedDBCallbacks(this, params.ipc_thread_id, | 343 callbacks, origin, indexed_db_path, request_context_getter_); |
322 params.ipc_callbacks_id), | |
323 params.origin, indexed_db_path, request_context_getter_); | |
324 } | 344 } |
325 | 345 |
326 void IndexedDBDispatcherHost::OnIDBFactoryOpen( | 346 void IndexedDBDispatcherHost::OpenOnIDBThread( |
327 const IndexedDBHostMsg_FactoryOpen_Params& params) { | 347 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 348 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
| 349 const url::Origin& origin, |
| 350 const base::string16& name, |
| 351 int64_t version, |
| 352 int64_t transaction_id) { |
328 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); | 353 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); |
329 | 354 |
330 if (!IsValidOrigin(params.origin)) { | |
331 bad_message::ReceivedBadMessage(this, bad_message::IDBDH_INVALID_ORIGIN); | |
332 return; | |
333 } | |
334 | |
335 base::TimeTicks begin_time = base::TimeTicks::Now(); | 355 base::TimeTicks begin_time = base::TimeTicks::Now(); |
336 base::FilePath indexed_db_path = indexed_db_context_->data_path(); | 356 base::FilePath indexed_db_path = indexed_db_context_->data_path(); |
337 | 357 |
338 int64_t host_transaction_id = HostTransactionId(params.transaction_id); | 358 int64_t host_transaction_id = HostTransactionId(transaction_id); |
339 | 359 |
340 // TODO(dgrogan): Don't let a non-existing database be opened (and therefore | 360 // TODO(dgrogan): Don't let a non-existing database be opened (and therefore |
341 // created) if this origin is already over quota. | 361 // created) if this origin is already over quota. |
342 scoped_refptr<IndexedDBCallbacks> callbacks = new IndexedDBCallbacks( | |
343 this, params.ipc_thread_id, params.ipc_callbacks_id, | |
344 params.ipc_database_callbacks_id, host_transaction_id, params.origin); | |
345 callbacks->SetConnectionOpenStartTime(begin_time); | 362 callbacks->SetConnectionOpenStartTime(begin_time); |
346 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks = | 363 callbacks->set_host_transaction_id(host_transaction_id); |
347 new IndexedDBDatabaseCallbacks( | |
348 this, params.ipc_thread_id, params.ipc_database_callbacks_id); | |
349 std::unique_ptr<IndexedDBPendingConnection> connection = | 364 std::unique_ptr<IndexedDBPendingConnection> connection = |
350 base::MakeUnique<IndexedDBPendingConnection>( | 365 base::MakeUnique<IndexedDBPendingConnection>( |
351 callbacks, database_callbacks, ipc_process_id_, host_transaction_id, | 366 callbacks, database_callbacks, ipc_process_id_, host_transaction_id, |
352 params.version); | 367 version); |
353 DCHECK(request_context_getter_); | 368 DCHECK(request_context_getter_); |
354 context()->GetIDBFactory()->Open(params.name, std::move(connection), | 369 context()->GetIDBFactory()->Open(name, std::move(connection), |
355 request_context_getter_, params.origin, | 370 request_context_getter_, origin, |
356 indexed_db_path); | 371 indexed_db_path); |
357 } | 372 } |
358 | 373 |
359 void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase( | 374 void IndexedDBDispatcherHost::DeleteDatabaseOnIDBThread( |
360 const IndexedDBHostMsg_FactoryDeleteDatabase_Params& params) { | 375 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 376 const url::Origin& origin, |
| 377 const base::string16& name) { |
361 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); | 378 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); |
362 | 379 |
363 if (!IsValidOrigin(params.origin)) { | |
364 bad_message::ReceivedBadMessage(this, bad_message::IDBDH_INVALID_ORIGIN); | |
365 return; | |
366 } | |
367 | |
368 base::FilePath indexed_db_path = indexed_db_context_->data_path(); | 380 base::FilePath indexed_db_path = indexed_db_context_->data_path(); |
369 DCHECK(request_context_getter_); | 381 DCHECK(request_context_getter_); |
370 context()->GetIDBFactory()->DeleteDatabase( | 382 context()->GetIDBFactory()->DeleteDatabase( |
371 params.name, request_context_getter_, | 383 name, request_context_getter_, callbacks, origin, indexed_db_path); |
372 new IndexedDBCallbacks(this, params.ipc_thread_id, | |
373 params.ipc_callbacks_id), | |
374 params.origin, indexed_db_path); | |
375 } | 384 } |
376 | 385 |
377 // OnPutHelper exists only to allow us to hop threads while holding a reference | 386 // OnPutHelper exists only to allow us to hop threads while holding a reference |
378 // to the IndexedDBDispatcherHost. | 387 // to the IndexedDBDispatcherHost. |
379 void IndexedDBDispatcherHost::OnPutHelper( | 388 void IndexedDBDispatcherHost::OnPutHelper( |
380 const IndexedDBHostMsg_DatabasePut_Params& params, | 389 const IndexedDBHostMsg_DatabasePut_Params& params, |
381 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles) { | 390 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles) { |
382 database_dispatcher_host_->OnPut(params, std::move(handles)); | 391 database_dispatcher_host_->OnPut(params, std::move(handles)); |
383 } | 392 } |
384 | 393 |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 DLOG(ERROR) << "Unable to reset prefetch"; | 1101 DLOG(ERROR) << "Unable to reset prefetch"; |
1093 } | 1102 } |
1094 | 1103 |
1095 void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed( | 1104 void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed( |
1096 int32_t ipc_object_id) { | 1105 int32_t ipc_object_id) { |
1097 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread()); | 1106 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread()); |
1098 parent_->DestroyObject(&map_, ipc_object_id); | 1107 parent_->DestroyObject(&map_, ipc_object_id); |
1099 } | 1108 } |
1100 | 1109 |
1101 } // namespace content | 1110 } // namespace content |
OLD | NEW |