| 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/in_process_webkit/indexed_db_key_utility_client.h" | 5 #include "content/browser/in_process_webkit/indexed_db_key_utility_client.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "content/browser/utility_process_host_impl.h" | 10 #include "content/browser/utility_process_host_impl.h" |
| 11 #include "content/common/indexed_db/indexed_db_key.h" | 11 #include "content/common/indexed_db/indexed_db_key.h" |
| 12 #include "content/common/indexed_db/indexed_db_key_path.h" |
| 12 #include "content/common/indexed_db/indexed_db_messages.h" | 13 #include "content/common/indexed_db/indexed_db_messages.h" |
| 13 #include "content/common/utility_messages.h" | 14 #include "content/common/utility_messages.h" |
| 14 #include "content/public/browser/utility_process_host_client.h" | 15 #include "content/public/browser/utility_process_host_client.h" |
| 15 #include "content/public/common/serialized_script_value.h" | 16 #include "content/public/common/serialized_script_value.h" |
| 16 | 17 |
| 17 using content::BrowserThread; | 18 using content::BrowserThread; |
| 19 using content::IndexedDBKeyPath; |
| 18 using content::UtilityProcessHostClient; | 20 using content::UtilityProcessHostClient; |
| 19 | 21 |
| 20 // This class is used to obtain IndexedDBKeys from SerializedScriptValues | 22 // This class is used to obtain IndexedDBKeys from SerializedScriptValues |
| 21 // given an IDBKeyPath. It uses UtilityProcess to do this inside a sandbox | 23 // given an IDBKeyPath. It uses UtilityProcess to do this inside a sandbox |
| 22 // (a V8 lock is required there). At this level, all methods are synchronous | 24 // (a V8 lock is required there). At this level, all methods are synchronous |
| 23 // as required by the caller. The public API is used on WEBKIT thread, | 25 // as required by the caller. The public API is used on WEBKIT thread, |
| 24 // but internally it moves around to UI and IO as needed. | 26 // but internally it moves around to UI and IO as needed. |
| 25 class KeyUtilityClientImpl | 27 class KeyUtilityClientImpl |
| 26 : public base::RefCountedThreadSafe<KeyUtilityClientImpl> { | 28 : public base::RefCountedThreadSafe<KeyUtilityClientImpl> { |
| 27 public: | 29 public: |
| 28 KeyUtilityClientImpl(); | 30 KeyUtilityClientImpl(); |
| 29 | 31 |
| 30 // Starts the UtilityProcess. Must be called before any other method. | 32 // Starts the UtilityProcess. Must be called before any other method. |
| 31 void StartUtilityProcess(); | 33 void StartUtilityProcess(); |
| 32 | 34 |
| 33 // Stops the UtilityProcess. No further keys can be created after this. | 35 // Stops the UtilityProcess. No further keys can be created after this. |
| 34 void Shutdown(); | 36 void Shutdown(); |
| 35 | 37 |
| 36 // Synchronously obtain the |keys| from |values| for the given |key_path|. | 38 // Synchronously obtain the |keys| from |values| for the given |key_path|. |
| 37 void CreateIDBKeysFromSerializedValuesAndKeyPath( | 39 void CreateIDBKeysFromSerializedValuesAndKeyPath( |
| 38 const std::vector<content::SerializedScriptValue>& values, | 40 const std::vector<content::SerializedScriptValue>& values, |
| 39 const string16& key_path, | 41 const IndexedDBKeyPath& key_path, |
| 40 std::vector<IndexedDBKey>* keys); | 42 std::vector<IndexedDBKey>* keys); |
| 41 | 43 |
| 42 // Synchronously inject |key| into |value| using the given |key_path|, | 44 // Synchronously inject |key| into |value| using the given |key_path|, |
| 43 // returning the new value. | 45 // returning the new value. |
| 44 content::SerializedScriptValue InjectIDBKeyIntoSerializedValue( | 46 content::SerializedScriptValue InjectIDBKeyIntoSerializedValue( |
| 45 const IndexedDBKey& key, | 47 const IndexedDBKey& key, |
| 46 const content::SerializedScriptValue& value, | 48 const content::SerializedScriptValue& value, |
| 47 const string16& key_path); | 49 const IndexedDBKeyPath& key_path); |
| 48 | 50 |
| 49 private: | 51 private: |
| 50 class Client : public UtilityProcessHostClient { | 52 class Client : public UtilityProcessHostClient { |
| 51 public: | 53 public: |
| 52 explicit Client(KeyUtilityClientImpl* parent); | 54 explicit Client(KeyUtilityClientImpl* parent); |
| 53 | 55 |
| 54 // UtilityProcessHostClient | 56 // UtilityProcessHostClient |
| 55 virtual void OnProcessCrashed(int exit_code); | 57 virtual void OnProcessCrashed(int exit_code); |
| 56 virtual bool OnMessageReceived(const IPC::Message& message); | 58 virtual bool OnMessageReceived(const IPC::Message& message); |
| 57 | 59 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 70 }; | 72 }; |
| 71 | 73 |
| 72 friend class base::RefCountedThreadSafe<KeyUtilityClientImpl>; | 74 friend class base::RefCountedThreadSafe<KeyUtilityClientImpl>; |
| 73 ~KeyUtilityClientImpl(); | 75 ~KeyUtilityClientImpl(); |
| 74 | 76 |
| 75 void GetRDHAndStartUtilityProcess(); | 77 void GetRDHAndStartUtilityProcess(); |
| 76 void StartUtilityProcessInternal(); | 78 void StartUtilityProcessInternal(); |
| 77 void EndUtilityProcessInternal(); | 79 void EndUtilityProcessInternal(); |
| 78 void CallStartIDBKeyFromValueAndKeyPathFromIOThread( | 80 void CallStartIDBKeyFromValueAndKeyPathFromIOThread( |
| 79 const std::vector<content::SerializedScriptValue>& values, | 81 const std::vector<content::SerializedScriptValue>& values, |
| 80 const string16& key_path); | 82 const IndexedDBKeyPath& key_path); |
| 81 void CallStartInjectIDBKeyFromIOThread( | 83 void CallStartInjectIDBKeyFromIOThread( |
| 82 const IndexedDBKey& key, | 84 const IndexedDBKey& key, |
| 83 const content::SerializedScriptValue& value, | 85 const content::SerializedScriptValue& value, |
| 84 const string16& key_path); | 86 const IndexedDBKeyPath& key_path); |
| 85 | 87 |
| 86 void SetKeys(const std::vector<IndexedDBKey>& keys); | 88 void SetKeys(const std::vector<IndexedDBKey>& keys); |
| 87 void FinishCreatingKeys(); | 89 void FinishCreatingKeys(); |
| 88 void SetValueAfterInjection(const content::SerializedScriptValue& value); | 90 void SetValueAfterInjection(const content::SerializedScriptValue& value); |
| 89 void FinishInjectingKey(); | 91 void FinishInjectingKey(); |
| 90 | 92 |
| 91 base::WaitableEvent waitable_event_; | 93 base::WaitableEvent waitable_event_; |
| 92 | 94 |
| 93 // Used in both IO and WEBKIT threads, but guarded by WaitableEvent, i.e., | 95 // Used in both IO and WEBKIT threads, but guarded by WaitableEvent, i.e., |
| 94 // these members are only set / read when the other thread is blocked. | 96 // these members are only set / read when the other thread is blocked. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 if (!instance->impl_) | 133 if (!instance->impl_) |
| 132 return; | 134 return; |
| 133 | 135 |
| 134 instance->is_shutdown_ = true; | 136 instance->is_shutdown_ = true; |
| 135 instance->impl_->Shutdown(); | 137 instance->impl_->Shutdown(); |
| 136 } | 138 } |
| 137 | 139 |
| 138 // static | 140 // static |
| 139 void IndexedDBKeyUtilityClient::CreateIDBKeysFromSerializedValuesAndKeyPath( | 141 void IndexedDBKeyUtilityClient::CreateIDBKeysFromSerializedValuesAndKeyPath( |
| 140 const std::vector<content::SerializedScriptValue>& values, | 142 const std::vector<content::SerializedScriptValue>& values, |
| 141 const string16& key_path, | 143 const IndexedDBKeyPath& key_path, |
| 142 std::vector<IndexedDBKey>* keys) { | 144 std::vector<IndexedDBKey>* keys) { |
| 143 IndexedDBKeyUtilityClient* instance = client_instance.Pointer(); | 145 IndexedDBKeyUtilityClient* instance = client_instance.Pointer(); |
| 144 | 146 |
| 145 if (instance->is_shutdown_) { | 147 if (instance->is_shutdown_) { |
| 146 keys->clear(); | 148 keys->clear(); |
| 147 return; | 149 return; |
| 148 } | 150 } |
| 149 | 151 |
| 150 if (!instance->impl_) { | 152 if (!instance->impl_) { |
| 151 instance->impl_ = new KeyUtilityClientImpl(); | 153 instance->impl_ = new KeyUtilityClientImpl(); |
| 152 instance->impl_->StartUtilityProcess(); | 154 instance->impl_->StartUtilityProcess(); |
| 153 } | 155 } |
| 154 | 156 |
| 155 instance->impl_->CreateIDBKeysFromSerializedValuesAndKeyPath(values, key_path, | 157 instance->impl_->CreateIDBKeysFromSerializedValuesAndKeyPath(values, key_path, |
| 156 keys); | 158 keys); |
| 157 } | 159 } |
| 158 | 160 |
| 159 // static | 161 // static |
| 160 content::SerializedScriptValue | 162 content::SerializedScriptValue |
| 161 IndexedDBKeyUtilityClient::InjectIDBKeyIntoSerializedValue( | 163 IndexedDBKeyUtilityClient::InjectIDBKeyIntoSerializedValue( |
| 162 const IndexedDBKey& key, const content::SerializedScriptValue& value, | 164 const IndexedDBKey& key, const content::SerializedScriptValue& value, |
| 163 const string16& key_path) { | 165 const IndexedDBKeyPath& key_path) { |
| 164 IndexedDBKeyUtilityClient* instance = client_instance.Pointer(); | 166 IndexedDBKeyUtilityClient* instance = client_instance.Pointer(); |
| 165 | 167 |
| 166 if (instance->is_shutdown_) | 168 if (instance->is_shutdown_) |
| 167 return content::SerializedScriptValue(); | 169 return content::SerializedScriptValue(); |
| 168 | 170 |
| 169 if (!instance->impl_) { | 171 if (!instance->impl_) { |
| 170 instance->impl_ = new KeyUtilityClientImpl(); | 172 instance->impl_ = new KeyUtilityClientImpl(); |
| 171 instance->impl_->StartUtilityProcess(); | 173 instance->impl_->StartUtilityProcess(); |
| 172 } | 174 } |
| 173 | 175 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 DCHECK(state_ == STATE_UNINITIALIZED); | 207 DCHECK(state_ == STATE_UNINITIALIZED); |
| 206 | 208 |
| 207 GetRDHAndStartUtilityProcess(); | 209 GetRDHAndStartUtilityProcess(); |
| 208 waitable_event_.Wait(); | 210 waitable_event_.Wait(); |
| 209 | 211 |
| 210 DCHECK(state_ == STATE_INITIALIZED); | 212 DCHECK(state_ == STATE_INITIALIZED); |
| 211 } | 213 } |
| 212 | 214 |
| 213 void KeyUtilityClientImpl::CreateIDBKeysFromSerializedValuesAndKeyPath( | 215 void KeyUtilityClientImpl::CreateIDBKeysFromSerializedValuesAndKeyPath( |
| 214 const std::vector<content::SerializedScriptValue>& values, | 216 const std::vector<content::SerializedScriptValue>& values, |
| 215 const string16& key_path, | 217 const IndexedDBKeyPath& key_path, |
| 216 std::vector<IndexedDBKey>* keys) { | 218 std::vector<IndexedDBKey>* keys) { |
| 217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 218 if (state_ == STATE_SHUTDOWN) { | 220 if (state_ == STATE_SHUTDOWN) { |
| 219 keys->clear(); | 221 keys->clear(); |
| 220 return; | 222 return; |
| 221 } | 223 } |
| 222 | 224 |
| 223 DCHECK(state_ == STATE_INITIALIZED); | 225 DCHECK(state_ == STATE_INITIALIZED); |
| 224 | 226 |
| 225 state_ = STATE_CREATING_KEYS; | 227 state_ = STATE_CREATING_KEYS; |
| 226 CallStartIDBKeyFromValueAndKeyPathFromIOThread(values, key_path); | 228 CallStartIDBKeyFromValueAndKeyPathFromIOThread(values, key_path); |
| 227 waitable_event_.Wait(); | 229 waitable_event_.Wait(); |
| 228 DCHECK(state_ == STATE_INITIALIZED); | 230 DCHECK(state_ == STATE_INITIALIZED); |
| 229 | 231 |
| 230 *keys = keys_; | 232 *keys = keys_; |
| 231 } | 233 } |
| 232 | 234 |
| 233 content::SerializedScriptValue | 235 content::SerializedScriptValue |
| 234 KeyUtilityClientImpl::InjectIDBKeyIntoSerializedValue( | 236 KeyUtilityClientImpl::InjectIDBKeyIntoSerializedValue( |
| 235 const IndexedDBKey& key, | 237 const IndexedDBKey& key, |
| 236 const content::SerializedScriptValue& value, | 238 const content::SerializedScriptValue& value, |
| 237 const string16& key_path) { | 239 const IndexedDBKeyPath& key_path) { |
| 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 239 if (state_ == STATE_SHUTDOWN) | 241 if (state_ == STATE_SHUTDOWN) |
| 240 return content::SerializedScriptValue(); | 242 return content::SerializedScriptValue(); |
| 241 | 243 |
| 242 DCHECK(state_ == STATE_INITIALIZED); | 244 DCHECK(state_ == STATE_INITIALIZED); |
| 243 | 245 |
| 244 state_ = STATE_INJECTING_KEY; | 246 state_ = STATE_INJECTING_KEY; |
| 245 CallStartInjectIDBKeyFromIOThread(key, value, key_path); | 247 CallStartInjectIDBKeyFromIOThread(key, value, key_path); |
| 246 | 248 |
| 247 waitable_event_.Wait(); | 249 waitable_event_.Wait(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 utility_process_host_->EndBatchMode(); | 301 utility_process_host_->EndBatchMode(); |
| 300 utility_process_host_.reset(); | 302 utility_process_host_.reset(); |
| 301 } | 303 } |
| 302 client_ = NULL; | 304 client_ = NULL; |
| 303 state_ = STATE_SHUTDOWN; | 305 state_ = STATE_SHUTDOWN; |
| 304 waitable_event_.Signal(); | 306 waitable_event_.Signal(); |
| 305 } | 307 } |
| 306 | 308 |
| 307 void KeyUtilityClientImpl::CallStartIDBKeyFromValueAndKeyPathFromIOThread( | 309 void KeyUtilityClientImpl::CallStartIDBKeyFromValueAndKeyPathFromIOThread( |
| 308 const std::vector<content::SerializedScriptValue>& values, | 310 const std::vector<content::SerializedScriptValue>& values, |
| 309 const string16& key_path) { | 311 const IndexedDBKeyPath& key_path) { |
| 310 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 312 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 311 BrowserThread::PostTask( | 313 BrowserThread::PostTask( |
| 312 BrowserThread::IO, FROM_HERE, | 314 BrowserThread::IO, FROM_HERE, |
| 313 base::Bind(&KeyUtilityClientImpl:: | 315 base::Bind(&KeyUtilityClientImpl:: |
| 314 CallStartIDBKeyFromValueAndKeyPathFromIOThread, | 316 CallStartIDBKeyFromValueAndKeyPathFromIOThread, |
| 315 this, values, key_path)); | 317 this, values, key_path)); |
| 316 return; | 318 return; |
| 317 } | 319 } |
| 318 | 320 |
| 319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 320 if (utility_process_host_) { | 322 if (utility_process_host_) { |
| 321 utility_process_host_->Send(new UtilityMsg_IDBKeysFromValuesAndKeyPath( | 323 utility_process_host_->Send(new UtilityMsg_IDBKeysFromValuesAndKeyPath( |
| 322 0, values, key_path)); | 324 0, values, key_path)); |
| 323 } | 325 } |
| 324 } | 326 } |
| 325 | 327 |
| 326 void KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread( | 328 void KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread( |
| 327 const IndexedDBKey& key, | 329 const IndexedDBKey& key, |
| 328 const content::SerializedScriptValue& value, | 330 const content::SerializedScriptValue& value, |
| 329 const string16& key_path) { | 331 const IndexedDBKeyPath& key_path) { |
| 330 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 332 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 331 BrowserThread::PostTask( | 333 BrowserThread::PostTask( |
| 332 BrowserThread::IO, FROM_HERE, | 334 BrowserThread::IO, FROM_HERE, |
| 333 base::Bind(&KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread, | 335 base::Bind(&KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread, |
| 334 this, key, value, key_path)); | 336 this, key, value, key_path)); |
| 335 return; | 337 return; |
| 336 } | 338 } |
| 337 | 339 |
| 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 339 if (utility_process_host_) | 341 if (utility_process_host_) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 parent_->FinishCreatingKeys(); | 375 parent_->FinishCreatingKeys(); |
| 374 parent_->Shutdown(); | 376 parent_->Shutdown(); |
| 375 } | 377 } |
| 376 | 378 |
| 377 bool KeyUtilityClientImpl::Client::OnMessageReceived( | 379 bool KeyUtilityClientImpl::Client::OnMessageReceived( |
| 378 const IPC::Message& message) { | 380 const IPC::Message& message) { |
| 379 bool handled = true; | 381 bool handled = true; |
| 380 IPC_BEGIN_MESSAGE_MAP(KeyUtilityClientImpl::Client, message) | 382 IPC_BEGIN_MESSAGE_MAP(KeyUtilityClientImpl::Client, message) |
| 381 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Succeeded, | 383 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Succeeded, |
| 382 OnIDBKeysFromValuesAndKeyPathSucceeded) | 384 OnIDBKeysFromValuesAndKeyPathSucceeded) |
| 383 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Failed, | |
| 384 OnIDBKeysFromValuesAndKeyPathFailed) | |
| 385 IPC_MESSAGE_HANDLER(UtilityHostMsg_InjectIDBKey_Finished, | 385 IPC_MESSAGE_HANDLER(UtilityHostMsg_InjectIDBKey_Finished, |
| 386 OnInjectIDBKeyFinished) | 386 OnInjectIDBKeyFinished) |
| 387 IPC_MESSAGE_UNHANDLED(handled = false) | 387 IPC_MESSAGE_UNHANDLED(handled = false) |
| 388 IPC_END_MESSAGE_MAP() | 388 IPC_END_MESSAGE_MAP() |
| 389 return handled; | 389 return handled; |
| 390 } | 390 } |
| 391 | 391 |
| 392 void KeyUtilityClientImpl::Client::OnIDBKeysFromValuesAndKeyPathSucceeded( | 392 void KeyUtilityClientImpl::Client::OnIDBKeysFromValuesAndKeyPathSucceeded( |
| 393 int id, const std::vector<IndexedDBKey>& keys) { | 393 int id, const std::vector<IndexedDBKey>& keys) { |
| 394 parent_->SetKeys(keys); | 394 parent_->SetKeys(keys); |
| 395 parent_->FinishCreatingKeys(); | 395 parent_->FinishCreatingKeys(); |
| 396 } | 396 } |
| 397 | 397 |
| 398 void KeyUtilityClientImpl::Client::OnInjectIDBKeyFinished( | 398 void KeyUtilityClientImpl::Client::OnInjectIDBKeyFinished( |
| 399 const content::SerializedScriptValue& value) { | 399 const content::SerializedScriptValue& value) { |
| 400 parent_->SetValueAfterInjection(value); | 400 parent_->SetValueAfterInjection(value); |
| 401 parent_->FinishInjectingKey(); | 401 parent_->FinishInjectingKey(); |
| 402 } | 402 } |
| 403 | 403 |
| 404 void KeyUtilityClientImpl::Client::OnIDBKeysFromValuesAndKeyPathFailed( | 404 void KeyUtilityClientImpl::Client::OnIDBKeysFromValuesAndKeyPathFailed( |
| 405 int id) { | 405 int id) { |
| 406 parent_->FinishCreatingKeys(); | 406 parent_->FinishCreatingKeys(); |
| 407 } | 407 } |
| OLD | NEW |