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