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 |