1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
6
7 #include <utility>
8
9 #include "build/build_config.h"
10 #include "mojo/public/cpp/bindings/pending_receiver.h"
11 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
12 #include "third_party/blink/public/platform/file_path_conversion.h"
13 #include "third_party/blink/public/platform/platform.h"
14 #include "third_party/blink/public/platform/task_type.h"
15 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
16 #include "third_party/blink/renderer/platform/wtf/functional.h"
17 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
18
19 namespace blink {
20
21 class FileSystemDispatcher::WriteListener
22 : public mojom::blink::FileSystemOperationListener {
23 public:
WriteListener(const WriteCallback & success_callback,StatusCallback error_callback)24 WriteListener(const WriteCallback& success_callback,
25 StatusCallback error_callback)
26 : error_callback_(std::move(error_callback)),
27 write_callback_(success_callback) {}
28
ResultsRetrieved(Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,bool has_more)29 void ResultsRetrieved(
30 Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
31 bool has_more) override {
32 NOTREACHED();
33 }
34
ErrorOccurred(base::File::Error error_code)35 void ErrorOccurred(base::File::Error error_code) override {
36 std::move(error_callback_).Run(error_code);
37 }
38
DidWrite(int64_t byte_count,bool complete)39 void DidWrite(int64_t byte_count, bool complete) override {
40 write_callback_.Run(byte_count, complete);
41 }
42
43 private:
44 StatusCallback error_callback_;
45 WriteCallback write_callback_;
46 };
47
48 class FileSystemDispatcher::ReadDirectoryListener
49 : public mojom::blink::FileSystemOperationListener {
50 public:
ReadDirectoryListener(std::unique_ptr<EntriesCallbacks> callbacks)51 explicit ReadDirectoryListener(std::unique_ptr<EntriesCallbacks> callbacks)
52 : callbacks_(std::move(callbacks)) {}
53
ResultsRetrieved(Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,bool has_more)54 void ResultsRetrieved(
55 Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
56 bool has_more) override {
57 for (const auto& entry : entries) {
58 callbacks_->DidReadDirectoryEntry(
59 FilePathToWebString(entry->name),
60 entry->type == filesystem::mojom::blink::FsFileType::DIRECTORY);
61 }
62 callbacks_->DidReadDirectoryEntries(has_more);
63 }
64
ErrorOccurred(base::File::Error error_code)65 void ErrorOccurred(base::File::Error error_code) override {
66 callbacks_->DidFail(error_code);
67 }
68
DidWrite(int64_t byte_count,bool complete)69 void DidWrite(int64_t byte_count, bool complete) override { NOTREACHED(); }
70
71 private:
72 std::unique_ptr<EntriesCallbacks> callbacks_;
73 };
74
FileSystemDispatcher(ExecutionContext & context)75 FileSystemDispatcher::FileSystemDispatcher(ExecutionContext& context)
76 : Supplement<ExecutionContext>(context),
77 file_system_manager_(&context),
78 next_operation_id_(1),
79 op_listeners_(&context) {}
80
81 // static
82 const char FileSystemDispatcher::kSupplementName[] = "FileSystemDispatcher";
83
84 // static
From(ExecutionContext * context)85 FileSystemDispatcher& FileSystemDispatcher::From(ExecutionContext* context) {
86 DCHECK(context);
87 FileSystemDispatcher* dispatcher =
88 Supplement<ExecutionContext>::From<FileSystemDispatcher>(context);
89 if (!dispatcher) {
90 dispatcher = MakeGarbageCollected<FileSystemDispatcher>(*context);
91 Supplement<ExecutionContext>::ProvideTo(*context, dispatcher);
92 }
93 return *dispatcher;
94 }
95
96 FileSystemDispatcher::~FileSystemDispatcher() = default;
97
GetFileSystemManager()98 mojom::blink::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() {
99 if (!file_system_manager_.is_bound()) {
100 // See https://bit.ly/2S0zRAS for task types
101 mojo::PendingReceiver<mojom::blink::FileSystemManager> receiver =
102 file_system_manager_.BindNewPipeAndPassReceiver(
103 GetSupplementable()->GetTaskRunner(
104 blink::TaskType::kMiscPlatformAPI));
105
106 GetSupplementable()->GetBrowserInterfaceBroker().GetInterface(
107 std::move(receiver));
108 }
109 DCHECK(file_system_manager_.is_bound());
110 return *file_system_manager_.get();
111 }
112
OpenFileSystem(const SecurityOrigin * origin,mojom::blink::FileSystemType type,std::unique_ptr<FileSystemCallbacks> callbacks)113 void FileSystemDispatcher::OpenFileSystem(
114 const SecurityOrigin* origin,
115 mojom::blink::FileSystemType type,
116 std::unique_ptr<FileSystemCallbacks> callbacks) {
117 GetFileSystemManager().Open(
118 origin, type,
119 WTF::Bind(&FileSystemDispatcher::DidOpenFileSystem,
120 WrapWeakPersistent(this), std::move(callbacks)));
121 }
122
OpenFileSystemSync(const SecurityOrigin * origin,mojom::blink::FileSystemType type,std::unique_ptr<FileSystemCallbacks> callbacks)123 void FileSystemDispatcher::OpenFileSystemSync(
124 const SecurityOrigin* origin,
125 mojom::blink::FileSystemType type,
126 std::unique_ptr<FileSystemCallbacks> callbacks) {
127 String name;
128 KURL root_url;
129 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
130 GetFileSystemManager().Open(origin, type, &name, &root_url, &error_code);
131 DidOpenFileSystem(std::move(callbacks), std::move(name), root_url,
132 error_code);
133 }
134
ResolveURL(const KURL & filesystem_url,std::unique_ptr<ResolveURICallbacks> callbacks)135 void FileSystemDispatcher::ResolveURL(
136 const KURL& filesystem_url,
137 std::unique_ptr<ResolveURICallbacks> callbacks) {
138 GetFileSystemManager().ResolveURL(
139 filesystem_url,
140 WTF::Bind(&FileSystemDispatcher::DidResolveURL, WrapWeakPersistent(this),
141 std::move(callbacks)));
142 }
143
ResolveURLSync(const KURL & filesystem_url,std::unique_ptr<ResolveURICallbacks> callbacks)144 void FileSystemDispatcher::ResolveURLSync(
145 const KURL& filesystem_url,
146 std::unique_ptr<ResolveURICallbacks> callbacks) {
147 mojom::blink::FileSystemInfoPtr info;
148 base::FilePath file_path;
149 bool is_directory;
150 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
151 GetFileSystemManager().ResolveURL(filesystem_url, &info, &file_path,
152 &is_directory, &error_code);
153 DidResolveURL(std::move(callbacks), std::move(info), std::move(file_path),
154 is_directory, error_code);
155 }
156
Move(const KURL & src_path,const KURL & dest_path,std::unique_ptr<EntryCallbacks> callbacks)157 void FileSystemDispatcher::Move(const KURL& src_path,
158 const KURL& dest_path,
159 std::unique_ptr<EntryCallbacks> callbacks) {
160 GetFileSystemManager().Move(
161 src_path, dest_path,
162 WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
163 std::move(callbacks)));
164 }
165
MoveSync(const KURL & src_path,const KURL & dest_path,std::unique_ptr<EntryCallbacks> callbacks)166 void FileSystemDispatcher::MoveSync(const KURL& src_path,
167 const KURL& dest_path,
168 std::unique_ptr<EntryCallbacks> callbacks) {
169 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
170 GetFileSystemManager().Move(src_path, dest_path, &error_code);
171 DidFinish(std::move(callbacks), error_code);
172 }
173
Copy(const KURL & src_path,const KURL & dest_path,std::unique_ptr<EntryCallbacks> callbacks)174 void FileSystemDispatcher::Copy(const KURL& src_path,
175 const KURL& dest_path,
176 std::unique_ptr<EntryCallbacks> callbacks) {
177 GetFileSystemManager().Copy(
178 src_path, dest_path,
179 WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
180 std::move(callbacks)));
181 }
182
CopySync(const KURL & src_path,const KURL & dest_path,std::unique_ptr<EntryCallbacks> callbacks)183 void FileSystemDispatcher::CopySync(const KURL& src_path,
184 const KURL& dest_path,
185 std::unique_ptr<EntryCallbacks> callbacks) {
186 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
187 GetFileSystemManager().Copy(src_path, dest_path, &error_code);
188 DidFinish(std::move(callbacks), error_code);
189 }
190
Remove(const KURL & path,bool recursive,std::unique_ptr<VoidCallbacks> callbacks)191 void FileSystemDispatcher::Remove(const KURL& path,
192 bool recursive,
193 std::unique_ptr<VoidCallbacks> callbacks) {
194 GetFileSystemManager().Remove(
195 path, recursive,
196 WTF::Bind(&FileSystemDispatcher::DidRemove, WrapWeakPersistent(this),
197 std::move(callbacks)));
198 }
199
RemoveSync(const KURL & path,bool recursive,std::unique_ptr<VoidCallbacks> callbacks)200 void FileSystemDispatcher::RemoveSync(
201 const KURL& path,
202 bool recursive,
203 std::unique_ptr<VoidCallbacks> callbacks) {
204 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
205 GetFileSystemManager().Remove(path, recursive, &error_code);
206 DidRemove(std::move(callbacks), error_code);
207 }
208
ReadMetadata(const KURL & path,std::unique_ptr<MetadataCallbacks> callbacks)209 void FileSystemDispatcher::ReadMetadata(
210 const KURL& path,
211 std::unique_ptr<MetadataCallbacks> callbacks) {
212 GetFileSystemManager().ReadMetadata(
213 path, WTF::Bind(&FileSystemDispatcher::DidReadMetadata,
214 WrapWeakPersistent(this), std::move(callbacks)));
215 }
216
ReadMetadataSync(const KURL & path,std::unique_ptr<MetadataCallbacks> callbacks)217 void FileSystemDispatcher::ReadMetadataSync(
218 const KURL& path,
219 std::unique_ptr<MetadataCallbacks> callbacks) {
220 base::File::Info file_info;
221 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
222 GetFileSystemManager().ReadMetadata(path, &file_info, &error_code);
223 DidReadMetadata(std::move(callbacks), std::move(file_info), error_code);
224 }
225
CreateFile(const KURL & path,bool exclusive,std::unique_ptr<EntryCallbacks> callbacks)226 void FileSystemDispatcher::CreateFile(
227 const KURL& path,
228 bool exclusive,
229 std::unique_ptr<EntryCallbacks> callbacks) {
230 GetFileSystemManager().Create(
231 path, exclusive, /*is_directory=*/false, /*is_recursive=*/false,
232 WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
233 std::move(callbacks)));
234 }
235
CreateFileSync(const KURL & path,bool exclusive,std::unique_ptr<EntryCallbacks> callbacks)236 void FileSystemDispatcher::CreateFileSync(
237 const KURL& path,
238 bool exclusive,
239 std::unique_ptr<EntryCallbacks> callbacks) {
240 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
241 GetFileSystemManager().Create(path, exclusive, /*is_directory=*/false,
242 /*is_recursive=*/false, &error_code);
243 DidFinish(std::move(callbacks), error_code);
244 }
245
CreateDirectory(const KURL & path,bool exclusive,bool recursive,std::unique_ptr<EntryCallbacks> callbacks)246 void FileSystemDispatcher::CreateDirectory(
247 const KURL& path,
248 bool exclusive,
249 bool recursive,
250 std::unique_ptr<EntryCallbacks> callbacks) {
251 GetFileSystemManager().Create(
252 path, exclusive, /*is_directory=*/true, recursive,
253 WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
254 std::move(callbacks)));
255 }
256
CreateDirectorySync(const KURL & path,bool exclusive,bool recursive,std::unique_ptr<EntryCallbacks> callbacks)257 void FileSystemDispatcher::CreateDirectorySync(
258 const KURL& path,
259 bool exclusive,
260 bool recursive,
261 std::unique_ptr<EntryCallbacks> callbacks) {
262 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
263 GetFileSystemManager().Create(path, exclusive, /*is_directory=*/true,
264 recursive, &error_code);
265 DidFinish(std::move(callbacks), error_code);
266 }
267
Exists(const KURL & path,bool is_directory,std::unique_ptr<EntryCallbacks> callbacks)268 void FileSystemDispatcher::Exists(const KURL& path,
269 bool is_directory,
270 std::unique_ptr<EntryCallbacks> callbacks) {
271 GetFileSystemManager().Exists(
272 path, is_directory,
273 WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this),
274 std::move(callbacks)));
275 }
276
ExistsSync(const KURL & path,bool is_directory,std::unique_ptr<EntryCallbacks> callbacks)277 void FileSystemDispatcher::ExistsSync(
278 const KURL& path,
279 bool is_directory,
280 std::unique_ptr<EntryCallbacks> callbacks) {
281 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
282 GetFileSystemManager().Exists(path, is_directory, &error_code);
283 DidFinish(std::move(callbacks), error_code);
284 }
285
ReadDirectory(const KURL & path,std::unique_ptr<EntriesCallbacks> callbacks)286 void FileSystemDispatcher::ReadDirectory(
287 const KURL& path,
288 std::unique_ptr<EntriesCallbacks> callbacks) {
289 mojo::PendingRemote<mojom::blink::FileSystemOperationListener> listener;
290 mojo::PendingReceiver<mojom::blink::FileSystemOperationListener> receiver =
291 listener.InitWithNewPipeAndPassReceiver();
292 op_listeners_.Add(
293 std::make_unique<ReadDirectoryListener>(std::move(callbacks)),
294 std::move(receiver),
295 // See https://bit.ly/2S0zRAS for task types
296 GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI));
297 GetFileSystemManager().ReadDirectory(path, std::move(listener));
298 }
299
ReadDirectorySync(const KURL & path,std::unique_ptr<EntriesCallbacks> callbacks)300 void FileSystemDispatcher::ReadDirectorySync(
301 const KURL& path,
302 std::unique_ptr<EntriesCallbacks> callbacks) {
303 Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries;
304 base::File::Error result = base::File::FILE_ERROR_FAILED;
305 GetFileSystemManager().ReadDirectorySync(path, &entries, &result);
306 if (result == base::File::FILE_OK) {
307 DidReadDirectory(std::move(callbacks), std::move(entries),
308 std::move(result));
309 }
310 }
311
InitializeFileWriter(const KURL & path,std::unique_ptr<FileWriterCallbacks> callbacks)312 void FileSystemDispatcher::InitializeFileWriter(
313 const KURL& path,
314 std::unique_ptr<FileWriterCallbacks> callbacks) {
315 GetFileSystemManager().ReadMetadata(
316 path, WTF::Bind(&FileSystemDispatcher::InitializeFileWriterCallback,
317 WrapWeakPersistent(this), path, std::move(callbacks)));
318 }
319
InitializeFileWriterSync(const KURL & path,std::unique_ptr<FileWriterCallbacks> callbacks)320 void FileSystemDispatcher::InitializeFileWriterSync(
321 const KURL& path,
322 std::unique_ptr<FileWriterCallbacks> callbacks) {
323 base::File::Info file_info;
324 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
325 GetFileSystemManager().ReadMetadata(path, &file_info, &error_code);
326 InitializeFileWriterCallback(path, std::move(callbacks), file_info,
327 error_code);
328 }
329
Truncate(const KURL & path,int64_t offset,int * request_id_out,StatusCallback callback)330 void FileSystemDispatcher::Truncate(const KURL& path,
331 int64_t offset,
332 int* request_id_out,
333 StatusCallback callback) {
334 HeapMojoRemote<mojom::blink::FileSystemCancellableOperation> op_remote(
335 GetSupplementable());
336 // See https://bit.ly/2S0zRAS for task types
337 mojo::PendingReceiver<mojom::blink::FileSystemCancellableOperation>
338 op_receiver = op_remote.BindNewPipeAndPassReceiver(
339 GetSupplementable()->GetTaskRunner(
340 blink::TaskType::kMiscPlatformAPI));
341 int operation_id = next_operation_id_++;
342 op_remote.set_disconnect_handler(
343 WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote,
344 WrapWeakPersistent(this), operation_id));
345 cancellable_operations_.insert(operation_id,
346 WrapDisallowNew(std::move(op_remote)));
347 GetFileSystemManager().Truncate(
348 path, offset, std::move(op_receiver),
349 WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this),
350 operation_id, std::move(callback)));
351
352 if (request_id_out)
353 *request_id_out = operation_id;
354 }
355
TruncateSync(const KURL & path,int64_t offset,StatusCallback callback)356 void FileSystemDispatcher::TruncateSync(const KURL& path,
357 int64_t offset,
358 StatusCallback callback) {
359 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
360 GetFileSystemManager().TruncateSync(path, offset, &error_code);
361 std::move(callback).Run(error_code);
362 }
363
Write(const KURL & path,const String & blob_id,int64_t offset,int * request_id_out,const WriteCallback & success_callback,StatusCallback error_callback)364 void FileSystemDispatcher::Write(const KURL& path,
365 const String& blob_id,
366 int64_t offset,
367 int* request_id_out,
368 const WriteCallback& success_callback,
369 StatusCallback error_callback) {
370 HeapMojoRemote<mojom::blink::FileSystemCancellableOperation> op_remote(
371 GetSupplementable());
372 // See https://bit.ly/2S0zRAS for task types
373 scoped_refptr<base::SequencedTaskRunner> task_runner =
374 GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI);
375 mojo::PendingReceiver<mojom::blink::FileSystemCancellableOperation>
376 op_receiver = op_remote.BindNewPipeAndPassReceiver(task_runner);
377 int operation_id = next_operation_id_++;
378 op_remote.set_disconnect_handler(
379 WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote,
380 WrapWeakPersistent(this), operation_id));
381 cancellable_operations_.insert(operation_id,
382 WrapDisallowNew(std::move(op_remote)));
383
384 mojo::PendingRemote<mojom::blink::FileSystemOperationListener> listener;
385 mojo::PendingReceiver<mojom::blink::FileSystemOperationListener> receiver =
386 listener.InitWithNewPipeAndPassReceiver();
387 op_listeners_.Add(std::make_unique<WriteListener>(
388 WTF::BindRepeating(&FileSystemDispatcher::DidWrite,
389 WrapWeakPersistent(this),
390 success_callback, operation_id),
391 WTF::Bind(&FileSystemDispatcher::WriteErrorCallback,
392 WrapWeakPersistent(this),
393 std::move(error_callback), operation_id)),
394 std::move(receiver), task_runner);
395
396 GetFileSystemManager().Write(path, blob_id, offset, std::move(op_receiver),
397 std::move(listener));
398
399 if (request_id_out)
400 *request_id_out = operation_id;
401 }
402
WriteSync(const KURL & path,const String & blob_id,int64_t offset,const WriteCallback & success_callback,StatusCallback error_callback)403 void FileSystemDispatcher::WriteSync(const KURL& path,
404 const String& blob_id,
405 int64_t offset,
406 const WriteCallback& success_callback,
407 StatusCallback error_callback) {
408 int64_t byte_count;
409 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
410 GetFileSystemManager().WriteSync(path, blob_id, offset, &byte_count,
411 &error_code);
412 if (error_code == base::File::FILE_OK)
413 std::move(success_callback).Run(byte_count, /*complete=*/true);
414 else
415 std::move(error_callback).Run(error_code);
416 }
417
Cancel(int request_id_to_cancel,StatusCallback callback)418 void FileSystemDispatcher::Cancel(int request_id_to_cancel,
419 StatusCallback callback) {
420 if (cancellable_operations_.find(request_id_to_cancel) ==
421 cancellable_operations_.end()) {
422 std::move(callback).Run(base::File::FILE_ERROR_INVALID_OPERATION);
423 return;
424 }
425 auto& remote =
426 cancellable_operations_.find(request_id_to_cancel)->value->Value();
427 if (!remote.is_bound()) {
428 RemoveOperationRemote(request_id_to_cancel);
429 std::move(callback).Run(base::File::FILE_ERROR_INVALID_OPERATION);
430 return;
431 }
432 remote->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel,
433 WrapWeakPersistent(this), std::move(callback),
434 request_id_to_cancel));
435 }
436
CreateSnapshotFile(const KURL & file_path,std::unique_ptr<SnapshotFileCallbackBase> callbacks)437 void FileSystemDispatcher::CreateSnapshotFile(
438 const KURL& file_path,
439 std::unique_ptr<SnapshotFileCallbackBase> callbacks) {
440 GetFileSystemManager().CreateSnapshotFile(
441 file_path, WTF::Bind(&FileSystemDispatcher::DidCreateSnapshotFile,
442 WrapWeakPersistent(this), std::move(callbacks)));
443 }
444
CreateSnapshotFileSync(const KURL & file_path,std::unique_ptr<SnapshotFileCallbackBase> callbacks)445 void FileSystemDispatcher::CreateSnapshotFileSync(
446 const KURL& file_path,
447 std::unique_ptr<SnapshotFileCallbackBase> callbacks) {
448 base::File::Info file_info;
449 base::FilePath platform_path;
450 base::File::Error error_code = base::File::FILE_ERROR_FAILED;
451 mojo::PendingRemote<mojom::blink::ReceivedSnapshotListener> listener;
452 GetFileSystemManager().CreateSnapshotFile(
453 file_path, &file_info, &platform_path, &error_code, &listener);
454 DidCreateSnapshotFile(std::move(callbacks), std::move(file_info),
455 std::move(platform_path), error_code,
456 std::move(listener));
457 }
458
Trace(Visitor * visitor) const459 void FileSystemDispatcher::Trace(Visitor* visitor) const {
460 visitor->Trace(file_system_manager_);
461 visitor->Trace(cancellable_operations_);
462 visitor->Trace(op_listeners_);
463 Supplement<ExecutionContext>::Trace(visitor);
464 }
465
DidOpenFileSystem(std::unique_ptr<FileSystemCallbacks> callbacks,const String & name,const KURL & root,base::File::Error error_code)466 void FileSystemDispatcher::DidOpenFileSystem(
467 std::unique_ptr<FileSystemCallbacks> callbacks,
468 const String& name,
469 const KURL& root,
470 base::File::Error error_code) {
471 if (error_code == base::File::Error::FILE_OK) {
472 callbacks->DidOpenFileSystem(name, root);
473 } else {
474 callbacks->DidFail(error_code);
475 }
476 }
477
DidResolveURL(std::unique_ptr<ResolveURICallbacks> callbacks,mojom::blink::FileSystemInfoPtr info,const base::FilePath & file_path,bool is_directory,base::File::Error error_code)478 void FileSystemDispatcher::DidResolveURL(
479 std::unique_ptr<ResolveURICallbacks> callbacks,
480 mojom::blink::FileSystemInfoPtr info,
481 const base::FilePath& file_path,
482 bool is_directory,
483 base::File::Error error_code) {
484 if (error_code == base::File::Error::FILE_OK) {
485 DCHECK(info->root_url.IsValid());
486 callbacks->DidResolveURL(info->name, info->root_url, info->mount_type,
487 FilePathToWebString(file_path), is_directory);
488 } else {
489 callbacks->DidFail(error_code);
490 }
491 }
492
DidRemove(std::unique_ptr<VoidCallbacks> callbacks,base::File::Error error_code)493 void FileSystemDispatcher::DidRemove(std::unique_ptr<VoidCallbacks> callbacks,
494 base::File::Error error_code) {
495 if (error_code == base::File::Error::FILE_OK)
496 callbacks->DidSucceed();
497 else
498 callbacks->DidFail(error_code);
499 }
500
DidFinish(std::unique_ptr<EntryCallbacks> callbacks,base::File::Error error_code)501 void FileSystemDispatcher::DidFinish(std::unique_ptr<EntryCallbacks> callbacks,
502 base::File::Error error_code) {
503 if (error_code == base::File::Error::FILE_OK)
504 callbacks->DidSucceed();
505 else
506 callbacks->DidFail(error_code);
507 }
508
DidReadMetadata(std::unique_ptr<MetadataCallbacks> callbacks,const base::File::Info & file_info,base::File::Error error_code)509 void FileSystemDispatcher::DidReadMetadata(
510 std::unique_ptr<MetadataCallbacks> callbacks,
511 const base::File::Info& file_info,
512 base::File::Error error_code) {
513 if (error_code == base::File::Error::FILE_OK) {
514 callbacks->DidReadMetadata(FileMetadata::From(file_info));
515 } else {
516 callbacks->DidFail(error_code);
517 }
518 }
519
DidReadDirectory(std::unique_ptr<EntriesCallbacks> callbacks,Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,base::File::Error error_code)520 void FileSystemDispatcher::DidReadDirectory(
521 std::unique_ptr<EntriesCallbacks> callbacks,
522 Vector<filesystem::mojom::blink::DirectoryEntryPtr> entries,
523 base::File::Error error_code) {
524 if (error_code == base::File::Error::FILE_OK) {
525 for (const auto& entry : entries) {
526 callbacks->DidReadDirectoryEntry(
527 FilePathToWebString(entry->name),
528 entry->type == filesystem::mojom::blink::FsFileType::DIRECTORY);
529 }
530 callbacks->DidReadDirectoryEntries(false);
531 } else {
532 callbacks->DidFail(error_code);
533 }
534 }
535
InitializeFileWriterCallback(const KURL & path,std::unique_ptr<FileWriterCallbacks> callbacks,const base::File::Info & file_info,base::File::Error error_code)536 void FileSystemDispatcher::InitializeFileWriterCallback(
537 const KURL& path,
538 std::unique_ptr<FileWriterCallbacks> callbacks,
539 const base::File::Info& file_info,
540 base::File::Error error_code) {
541 if (error_code == base::File::Error::FILE_OK) {
542 if (file_info.is_directory || file_info.size < 0) {
543 callbacks->DidFail(base::File::FILE_ERROR_FAILED);
544 return;
545 }
546 callbacks->DidCreateFileWriter(path, file_info.size);
547 } else {
548 callbacks->DidFail(error_code);
549 }
550 }
551
DidTruncate(int operation_id,StatusCallback callback,base::File::Error error_code)552 void FileSystemDispatcher::DidTruncate(int operation_id,
553 StatusCallback callback,
554 base::File::Error error_code) {
555 if (error_code != base::File::FILE_ERROR_ABORT)
556 RemoveOperationRemote(operation_id);
557 std::move(callback).Run(error_code);
558 }
559
DidWrite(const WriteCallback & callback,int operation_id,int64_t bytes,bool complete)560 void FileSystemDispatcher::DidWrite(const WriteCallback& callback,
561 int operation_id,
562 int64_t bytes,
563 bool complete) {
564 callback.Run(bytes, complete);
565 if (complete)
566 RemoveOperationRemote(operation_id);
567 }
568
WriteErrorCallback(StatusCallback callback,int operation_id,base::File::Error error)569 void FileSystemDispatcher::WriteErrorCallback(StatusCallback callback,
570 int operation_id,
571 base::File::Error error) {
572 std::move(callback).Run(error);
573 if (error != base::File::FILE_ERROR_ABORT)
574 RemoveOperationRemote(operation_id);
575 }
576
DidCancel(StatusCallback callback,int cancelled_operation_id,base::File::Error error_code)577 void FileSystemDispatcher::DidCancel(StatusCallback callback,
578 int cancelled_operation_id,
579 base::File::Error error_code) {
580 if (error_code == base::File::FILE_OK)
581 RemoveOperationRemote(cancelled_operation_id);
582 std::move(callback).Run(error_code);
583 }
584
DidCreateSnapshotFile(std::unique_ptr<SnapshotFileCallbackBase> callbacks,const base::File::Info & file_info,const base::FilePath & platform_path,base::File::Error error_code,mojo::PendingRemote<mojom::blink::ReceivedSnapshotListener> listener)585 void FileSystemDispatcher::DidCreateSnapshotFile(
586 std::unique_ptr<SnapshotFileCallbackBase> callbacks,
587 const base::File::Info& file_info,
588 const base::FilePath& platform_path,
589 base::File::Error error_code,
590 mojo::PendingRemote<mojom::blink::ReceivedSnapshotListener> listener) {
591 if (error_code == base::File::FILE_OK) {
592 FileMetadata file_metadata = FileMetadata::From(file_info);
593 file_metadata.platform_path = FilePathToWebString(platform_path);
594
595 callbacks->DidCreateSnapshotFile(file_metadata);
596
597 if (listener) {
598 mojo::Remote<mojom::blink::ReceivedSnapshotListener>(std::move(listener))
599 ->DidReceiveSnapshotFile();
600 }
601 } else {
602 callbacks->DidFail(error_code);
603 }
604 }
605
RemoveOperationRemote(int operation_id)606 void FileSystemDispatcher::RemoveOperationRemote(int operation_id) {
607 auto it = cancellable_operations_.find(operation_id);
608 if (it == cancellable_operations_.end())
609 return;
610 cancellable_operations_.erase(it);
611 }
612
613 } // namespace blink
614