OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/child/fileapi/webfilesystem_impl.h" | 5 #include "content/child/fileapi/webfilesystem_impl.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/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 DCHECK(!waitable_results); | 116 DCHECK(!waitable_results); |
117 DispatchToMethod(ChildThread::current()->file_system_dispatcher(), | 117 DispatchToMethod(ChildThread::current()->file_system_dispatcher(), |
118 method, params); | 118 method, params); |
119 } | 119 } |
120 | 120 |
121 enum CallbacksUnregisterMode { | 121 enum CallbacksUnregisterMode { |
122 UNREGISTER_CALLBACKS, | 122 UNREGISTER_CALLBACKS, |
123 DO_NOT_UNREGISTER_CALLBACKS, | 123 DO_NOT_UNREGISTER_CALLBACKS, |
124 }; | 124 }; |
125 | 125 |
| 126 // Bridging functions that convert the arguments into Blink objects |
| 127 // (e.g. WebFileInfo, WebString, WebVector<WebFileSystemEntry>) |
| 128 // and call WebFileSystemCallbacks's methods. |
| 129 // These are called by RunCallbacks after crossing threads to ensure |
| 130 // thread safety, because the Blink objects cannot be passed across |
| 131 // threads by base::Bind(). |
| 132 void DidSucceed(WebFileSystemCallbacks* callbacks) { |
| 133 callbacks->didSucceed(); |
| 134 } |
| 135 |
| 136 void DidReadMetadata(const base::File::Info& file_info, |
| 137 WebFileSystemCallbacks* callbacks) { |
| 138 WebFileInfo web_file_info; |
| 139 FileInfoToWebFileInfo(file_info, &web_file_info); |
| 140 callbacks->didReadMetadata(web_file_info); |
| 141 } |
| 142 |
| 143 void DidReadDirectory(const std::vector<fileapi::DirectoryEntry>& entries, |
| 144 bool has_more, WebFileSystemCallbacks* callbacks) { |
| 145 WebVector<WebFileSystemEntry> file_system_entries(entries.size()); |
| 146 for (size_t i = 0; i < entries.size(); ++i) { |
| 147 file_system_entries[i].name = |
| 148 base::FilePath(entries[i].name).AsUTF16Unsafe(); |
| 149 file_system_entries[i].isDirectory = entries[i].is_directory; |
| 150 } |
| 151 callbacks->didReadDirectory(file_system_entries, has_more); |
| 152 } |
| 153 |
| 154 void DidOpenFileSystem(const base::string16& name, const GURL& root, |
| 155 WebFileSystemCallbacks* callbacks) { |
| 156 callbacks->didOpenFileSystem(name, root); |
| 157 } |
| 158 |
| 159 void DidResolveURL( |
| 160 const base::string16& name, |
| 161 const GURL& root_url, |
| 162 fileapi::FileSystemType mount_type, |
| 163 const base::string16& file_path, |
| 164 bool is_directory, |
| 165 WebFileSystemCallbacks* callbacks) { |
| 166 callbacks->didResolveURL( |
| 167 name, |
| 168 root_url, |
| 169 static_cast<blink::WebFileSystemType>(mount_type), |
| 170 file_path, |
| 171 is_directory); |
| 172 } |
| 173 |
| 174 void DidFail(base::File::Error error, WebFileSystemCallbacks* callbacks) { |
| 175 callbacks->didFail(fileapi::FileErrorToWebFileError(error)); |
| 176 } |
| 177 |
126 // Run WebFileSystemCallbacks's |method| with |params|. | 178 // Run WebFileSystemCallbacks's |method| with |params|. |
127 template <typename Method, typename Params> | 179 void RunCallbacks( |
128 void RunCallbacks(int callbacks_id, Method method, const Params& params, | 180 int callbacks_id, |
129 CallbacksUnregisterMode callbacks_unregister_mode) { | 181 const base::Callback<void(WebFileSystemCallbacks*)>& callback, |
| 182 CallbacksUnregisterMode callbacks_unregister_mode) { |
130 WebFileSystemImpl* filesystem = | 183 WebFileSystemImpl* filesystem = |
131 WebFileSystemImpl::ThreadSpecificInstance(NULL); | 184 WebFileSystemImpl::ThreadSpecificInstance(NULL); |
132 if (!filesystem) | 185 if (!filesystem) |
133 return; | 186 return; |
134 WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id); | 187 WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id); |
135 if (callbacks_unregister_mode == UNREGISTER_CALLBACKS) | 188 if (callbacks_unregister_mode == UNREGISTER_CALLBACKS) |
136 filesystem->UnregisterCallbacks(callbacks_id); | 189 filesystem->UnregisterCallbacks(callbacks_id); |
137 DispatchToMethod(&callbacks, method, params); | 190 callback.Run(&callbacks); |
138 } | 191 } |
139 | 192 |
140 void DispatchResultsClosure(int thread_id, int callbacks_id, | 193 void DispatchResultsClosure(int thread_id, int callbacks_id, |
141 WaitableCallbackResults* waitable_results, | 194 WaitableCallbackResults* waitable_results, |
142 const base::Closure& results_closure) { | 195 const base::Closure& results_closure) { |
143 if (thread_id != CurrentWorkerId()) { | 196 if (thread_id != CurrentWorkerId()) { |
144 if (waitable_results) { | 197 if (waitable_results) { |
145 // If someone is waiting, this should result in running the closure. | 198 // If someone is waiting, this should result in running the closure. |
146 waitable_results->AddResultsAndSignal(results_closure); | 199 waitable_results->AddResultsAndSignal(results_closure); |
147 // In case no one is waiting, post a task to run the closure. | 200 // In case no one is waiting, post a task to run the closure. |
148 WorkerTaskRunner::Instance()->PostTask( | 201 WorkerTaskRunner::Instance()->PostTask( |
149 thread_id, | 202 thread_id, |
150 base::Bind(&WaitableCallbackResults::Run, | 203 base::Bind(&WaitableCallbackResults::Run, |
151 make_scoped_refptr(waitable_results))); | 204 make_scoped_refptr(waitable_results))); |
152 return; | 205 return; |
153 } | 206 } |
154 WorkerTaskRunner::Instance()->PostTask(thread_id, results_closure); | 207 WorkerTaskRunner::Instance()->PostTask(thread_id, results_closure); |
155 return; | 208 return; |
156 } | 209 } |
157 results_closure.Run(); | 210 results_closure.Run(); |
158 } | 211 } |
159 | 212 |
160 template <typename Method, typename Params> | |
161 void CallbackFileSystemCallbacks( | 213 void CallbackFileSystemCallbacks( |
162 int thread_id, int callbacks_id, | 214 int thread_id, int callbacks_id, |
163 WaitableCallbackResults* waitable_results, | 215 WaitableCallbackResults* waitable_results, |
164 Method method, const Params& params, | 216 const base::Callback<void(WebFileSystemCallbacks*)>& callback, |
165 CallbacksUnregisterMode callbacks_unregister_mode) { | 217 CallbacksUnregisterMode callbacksunregister_mode) { |
166 DispatchResultsClosure( | 218 DispatchResultsClosure( |
167 thread_id, callbacks_id, waitable_results, | 219 thread_id, callbacks_id, waitable_results, |
168 base::Bind(&RunCallbacks<Method, Params>, callbacks_id, method, params, | 220 base::Bind(&RunCallbacks, callbacks_id, callback, |
169 callbacks_unregister_mode)); | 221 callbacksunregister_mode)); |
170 } | 222 } |
171 | 223 |
172 //----------------------------------------------------------------------------- | 224 //----------------------------------------------------------------------------- |
173 // Callback adapters. Callbacks must be called on the original calling thread, | 225 // Callback adapters. Callbacks must be called on the original calling thread, |
174 // so these callback adapters relay back the results to the calling thread | 226 // so these callback adapters relay back the results to the calling thread |
175 // if necessary. | 227 // if necessary. |
176 | 228 |
177 void OpenFileSystemCallbackAdapter( | 229 void OpenFileSystemCallbackAdapter( |
178 int thread_id, int callbacks_id, | 230 int thread_id, int callbacks_id, |
179 WaitableCallbackResults* waitable_results, | 231 WaitableCallbackResults* waitable_results, |
180 const std::string& name, const GURL& root) { | 232 const std::string& name, const GURL& root) { |
181 CallbackFileSystemCallbacks( | 233 CallbackFileSystemCallbacks( |
182 thread_id, callbacks_id, waitable_results, | 234 thread_id, callbacks_id, waitable_results, |
183 &WebFileSystemCallbacks::didOpenFileSystem, | 235 base::Bind(&DidOpenFileSystem, base::UTF8ToUTF16(name), root), |
184 MakeTuple(base::UTF8ToUTF16(name), root), | |
185 UNREGISTER_CALLBACKS); | 236 UNREGISTER_CALLBACKS); |
186 } | 237 } |
187 | 238 |
188 void ResolveURLCallbackAdapter( | 239 void ResolveURLCallbackAdapter( |
189 int thread_id, int callbacks_id, | 240 int thread_id, int callbacks_id, |
190 WaitableCallbackResults* waitable_results, | 241 WaitableCallbackResults* waitable_results, |
191 const fileapi::FileSystemInfo& info, | 242 const fileapi::FileSystemInfo& info, |
192 const base::FilePath& file_path, bool is_directory) { | 243 const base::FilePath& file_path, bool is_directory) { |
193 base::FilePath normalized_path( | 244 base::FilePath normalized_path( |
194 fileapi::VirtualPath::GetNormalizedFilePath(file_path)); | 245 fileapi::VirtualPath::GetNormalizedFilePath(file_path)); |
195 CallbackFileSystemCallbacks( | 246 CallbackFileSystemCallbacks( |
196 thread_id, callbacks_id, waitable_results, | 247 thread_id, callbacks_id, waitable_results, |
197 &WebFileSystemCallbacks::didResolveURL, | 248 base::Bind(&DidResolveURL, base::UTF8ToUTF16(info.name), info.root_url, |
198 MakeTuple(base::UTF8ToUTF16(info.name), info.root_url, | 249 info.mount_type, |
199 static_cast<blink::WebFileSystemType>(info.mount_type), | 250 normalized_path.AsUTF16Unsafe(), is_directory), |
200 normalized_path.AsUTF16Unsafe(), is_directory), | |
201 UNREGISTER_CALLBACKS); | 251 UNREGISTER_CALLBACKS); |
202 } | 252 } |
203 | 253 |
204 void StatusCallbackAdapter(int thread_id, int callbacks_id, | 254 void StatusCallbackAdapter(int thread_id, int callbacks_id, |
205 WaitableCallbackResults* waitable_results, | 255 WaitableCallbackResults* waitable_results, |
206 base::File::Error error) { | 256 base::File::Error error) { |
207 if (error == base::File::FILE_OK) { | 257 if (error == base::File::FILE_OK) { |
208 CallbackFileSystemCallbacks( | 258 CallbackFileSystemCallbacks( |
209 thread_id, callbacks_id, waitable_results, | 259 thread_id, callbacks_id, waitable_results, |
210 &WebFileSystemCallbacks::didSucceed, MakeTuple(), | 260 base::Bind(&DidSucceed), |
211 UNREGISTER_CALLBACKS); | 261 UNREGISTER_CALLBACKS); |
212 } else { | 262 } else { |
213 CallbackFileSystemCallbacks( | 263 CallbackFileSystemCallbacks( |
214 thread_id, callbacks_id, waitable_results, | 264 thread_id, callbacks_id, waitable_results, |
215 &WebFileSystemCallbacks::didFail, | 265 base::Bind(&DidFail, error), |
216 MakeTuple(fileapi::FileErrorToWebFileError(error)), | |
217 UNREGISTER_CALLBACKS); | 266 UNREGISTER_CALLBACKS); |
218 } | 267 } |
219 } | 268 } |
220 | 269 |
221 void ReadMetadataCallbackAdapter(int thread_id, int callbacks_id, | 270 void ReadMetadataCallbackAdapter(int thread_id, int callbacks_id, |
222 WaitableCallbackResults* waitable_results, | 271 WaitableCallbackResults* waitable_results, |
223 const base::File::Info& file_info) { | 272 const base::File::Info& file_info) { |
224 WebFileInfo web_file_info; | |
225 FileInfoToWebFileInfo(file_info, &web_file_info); | |
226 CallbackFileSystemCallbacks( | 273 CallbackFileSystemCallbacks( |
227 thread_id, callbacks_id, waitable_results, | 274 thread_id, callbacks_id, waitable_results, |
228 &WebFileSystemCallbacks::didReadMetadata, | 275 base::Bind(&DidReadMetadata, file_info), |
229 MakeTuple(web_file_info), | |
230 UNREGISTER_CALLBACKS); | 276 UNREGISTER_CALLBACKS); |
231 } | 277 } |
232 | 278 |
233 void ReadDirectoryCallbackAdapter( | 279 void ReadDirectoryCallbackAdapter( |
234 int thread_id, int callbacks_id, WaitableCallbackResults* waitable_results, | 280 int thread_id, int callbacks_id, WaitableCallbackResults* waitable_results, |
235 const std::vector<fileapi::DirectoryEntry>& entries, | 281 const std::vector<fileapi::DirectoryEntry>& entries, |
236 bool has_more) { | 282 bool has_more) { |
237 WebVector<WebFileSystemEntry> file_system_entries(entries.size()); | |
238 for (size_t i = 0; i < entries.size(); i++) { | |
239 file_system_entries[i].name = | |
240 base::FilePath(entries[i].name).AsUTF16Unsafe(); | |
241 file_system_entries[i].isDirectory = entries[i].is_directory; | |
242 } | |
243 CallbackFileSystemCallbacks( | 283 CallbackFileSystemCallbacks( |
244 thread_id, callbacks_id, waitable_results, | 284 thread_id, callbacks_id, waitable_results, |
245 &WebFileSystemCallbacks::didReadDirectory, | 285 base::Bind(&DidReadDirectory, entries, has_more), |
246 MakeTuple(file_system_entries, has_more), | |
247 has_more ? DO_NOT_UNREGISTER_CALLBACKS : UNREGISTER_CALLBACKS); | 286 has_more ? DO_NOT_UNREGISTER_CALLBACKS : UNREGISTER_CALLBACKS); |
248 } | 287 } |
249 | 288 |
250 void DidCreateFileWriter( | 289 void DidCreateFileWriter( |
251 int callbacks_id, | 290 int callbacks_id, |
252 const GURL& path, | 291 const GURL& path, |
253 blink::WebFileWriterClient* client, | 292 blink::WebFileWriterClient* client, |
254 base::MessageLoopProxy* main_thread_loop, | 293 base::MessageLoopProxy* main_thread_loop, |
255 const base::File::Info& file_info) { | 294 const base::File::Info& file_info) { |
256 WebFileSystemImpl* filesystem = | 295 WebFileSystemImpl* filesystem = |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 WaitableCallbackResults* WebFileSystemImpl::MaybeCreateWaitableResults( | 685 WaitableCallbackResults* WebFileSystemImpl::MaybeCreateWaitableResults( |
647 const WebFileSystemCallbacks& callbacks, int callbacks_id) { | 686 const WebFileSystemCallbacks& callbacks, int callbacks_id) { |
648 if (!callbacks.shouldBlockUntilCompletion()) | 687 if (!callbacks.shouldBlockUntilCompletion()) |
649 return NULL; | 688 return NULL; |
650 WaitableCallbackResults* results = new WaitableCallbackResults(); | 689 WaitableCallbackResults* results = new WaitableCallbackResults(); |
651 waitable_results_[callbacks_id] = results; | 690 waitable_results_[callbacks_id] = results; |
652 return results; | 691 return results; |
653 } | 692 } |
654 | 693 |
655 } // namespace content | 694 } // namespace content |
OLD | NEW |