1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
content / browser / file_system / file_system_manager_impl.h [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_MANAGER_IMPL_H_
#define CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_MANAGER_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "base/containers/id_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "components/services/filesystem/public/mojom/types.mojom.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_operation_runner.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
class GURL;
namespace base {
class FilePath;
} // namespace base
namespace storage {
class FileSystemURL;
struct FileSystemInfo;
class ShareableFileReference;
} // namespace storage
namespace content {
class ChromeBlobStorageContext;
// All methods for this class are expected to be called on the IO thread,
// except for the constructor. The destructor must also be called on the IO
// thread as weak refs are created on that thread. A single instance of this
// class is owned by RenderProcessHostImpl.
class CONTENT_EXPORT FileSystemManagerImpl
: public blink::mojom::FileSystemManager {
public:
// Constructed and held by the RenderFrameHost and render process host on
// the UI thread. Used by render frames (via the RenderFrameHost), workers
// and pepper (via the render process host).
FileSystemManagerImpl(
int process_id,
scoped_refptr<storage::FileSystemContext> file_system_context,
scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
FileSystemManagerImpl(const FileSystemManagerImpl&) = delete;
FileSystemManagerImpl& operator=(const FileSystemManagerImpl&) = delete;
~FileSystemManagerImpl() override;
base::WeakPtr<FileSystemManagerImpl> GetWeakPtr();
void BindReceiver(
const blink::StorageKey& storage_key,
mojo::PendingReceiver<blink::mojom::FileSystemManager> receiver);
// blink::mojom::FileSystem
void Open(const url::Origin& origin,
blink::mojom::FileSystemType file_system_type,
OpenCallback callback) override;
void ResolveURL(const GURL& filesystem_url,
ResolveURLCallback callback) override;
void Move(const GURL& src_path,
const GURL& dest_path,
MoveCallback callback) override;
void Copy(const GURL& src_path,
const GURL& dest_path,
CopyCallback callback) override;
void Remove(const GURL& path,
bool recursive,
RemoveCallback callback) override;
void ReadMetadata(const GURL& path, ReadMetadataCallback callback) override;
void Create(const GURL& path,
bool exclusive,
bool is_directory,
bool recursive,
CreateCallback callback) override;
void Exists(const GURL& path,
bool is_directory,
ExistsCallback callback) override;
void ReadDirectory(
const GURL& path,
mojo::PendingRemote<blink::mojom::FileSystemOperationListener>
pending_listener) override;
void ReadDirectorySync(const GURL& path,
ReadDirectorySyncCallback callback) override;
void Write(const GURL& file_path,
mojo::PendingRemote<blink::mojom::Blob> blob,
int64_t position,
mojo::PendingReceiver<blink::mojom::FileSystemCancellableOperation>
op_receiver,
mojo::PendingRemote<blink::mojom::FileSystemOperationListener>
pending_listener) override;
void WriteSync(const GURL& file_path,
mojo::PendingRemote<blink::mojom::Blob> blob,
int64_t position,
WriteSyncCallback callback) override;
void Truncate(
const GURL& file_path,
int64_t length,
mojo::PendingReceiver<blink::mojom::FileSystemCancellableOperation>
op_receiver,
TruncateCallback callback) override;
void TruncateSync(const GURL& file_path,
int64_t length,
TruncateSyncCallback callback) override;
void CreateSnapshotFile(const GURL& file_path,
CreateSnapshotFileCallback callback) override;
void GetPlatformPath(const GURL& file_path,
GetPlatformPathCallback callback) override;
void RegisterBlob(const std::string& content_type,
const GURL& url,
uint64_t length,
std::optional<base::Time> expected_modification_time,
RegisterBlobCallback callback) override;
private:
class FileSystemCancellableOperationImpl;
class ReceivedSnapshotListenerImpl;
using OperationID = storage::FileSystemOperationRunner::OperationID;
using OperationListenerID = int;
struct WriteSyncCallbackEntry;
struct ReadDirectorySyncCallbackEntry;
void ContinueOpen(const url::Origin& origin,
blink::mojom::FileSystemType file_system_type,
mojo::ReportBadMessageCallback bad_message_callback,
OpenCallback callback,
const blink::StorageKey& storage_key,
bool security_check_success);
void ContinueResolveURL(const storage::FileSystemURL& url,
ResolveURLCallback callback,
bool security_check_success);
void ContinueMove(const storage::FileSystemURL& src_url,
const storage::FileSystemURL& dest_url,
MoveCallback callback,
bool security_check_success);
void ContinueCopy(const storage::FileSystemURL& src_url,
const storage::FileSystemURL& dest_url,
CopyCallback callback,
bool security_check_success);
void ContinueRemove(const storage::FileSystemURL& url,
bool recursive,
RemoveCallback callback,
bool security_check_success);
void ContinueReadMetadata(const storage::FileSystemURL& url,
ReadMetadataCallback callback,
bool security_check_success);
void ContinueCreate(const storage::FileSystemURL& url,
bool exclusive,
bool is_directory,
bool recursive,
CreateCallback callback,
bool security_check_success);
void ContinueExists(const storage::FileSystemURL& url,
bool is_directory,
ExistsCallback callback,
bool security_check_success);
void ContinueReadDirectory(
const storage::FileSystemURL& url,
mojo::Remote<blink::mojom::FileSystemOperationListener> listener,
bool security_check_success);
void ContinueReadDirectorySync(const storage::FileSystemURL& url,
ReadDirectorySyncCallback callback,
bool security_check_success);
void ResolveBlobForWrite(
mojo::PendingRemote<blink::mojom::Blob> blob,
base::OnceCallback<void(std::unique_ptr<storage::BlobDataHandle>)>
callback,
bool security_check_success);
void ContinueWrite(
const storage::FileSystemURL& url,
int64_t position,
mojo::PendingReceiver<blink::mojom::FileSystemCancellableOperation>
op_receiver,
mojo::Remote<blink::mojom::FileSystemOperationListener> listener,
std::unique_ptr<storage::BlobDataHandle> blob);
void ContinueWriteSync(const storage::FileSystemURL& url,
int64_t position,
WriteSyncCallback callback,
std::unique_ptr<storage::BlobDataHandle> blob);
void ContinueTruncate(
const storage::FileSystemURL& url,
int64_t length,
mojo::PendingReceiver<blink::mojom::FileSystemCancellableOperation>
op_receiver,
TruncateCallback callback,
bool security_check_success);
void ContinueTruncateSync(const storage::FileSystemURL& url,
int64_t length,
TruncateSyncCallback callback,
bool security_check_success);
void ContinueCreateSnapshotFile(const storage::FileSystemURL& url,
CreateSnapshotFileCallback callback,
bool security_check_success);
void ContinueRegisterBlob(
const std::string& content_type,
const GURL& url,
uint64_t length,
std::optional<base::Time> expected_modification_time,
RegisterBlobCallback callback,
storage::FileSystemURL crack_url,
bool security_check_success);
void Cancel(
OperationID op_id,
blink::mojom::FileSystemCancellableOperation::CancelCallback callback);
void DidReceiveSnapshotFile(int snapshot_id);
void OnConnectionError();
// Callback functions to be used when each file operation is finished.
void DidFinish(base::OnceCallback<void(base::File::Error)> callback,
base::File::Error error_code);
void DidGetMetadata(ReadMetadataCallback callback,
base::File::Error result,
const base::File::Info& info);
void DidGetMetadataForStreaming(CreateSnapshotFileCallback callback,
base::File::Error result,
const base::File::Info& info);
void DidReadDirectory(OperationListenerID listener_id,
base::File::Error result,
std::vector<filesystem::mojom::DirectoryEntry> entries,
bool has_more);
void DidReadDirectorySync(
ReadDirectorySyncCallbackEntry* callback_entry,
base::File::Error result,
std::vector<filesystem::mojom::DirectoryEntry> entries,
bool has_more);
void DidWrite(OperationListenerID listener_id,
base::File::Error result,
int64_t bytes,
bool complete);
void DidWriteSync(WriteSyncCallbackEntry* entry,
base::File::Error result,
int64_t bytes,
bool complete);
void DidOpenFileSystem(OpenCallback callback,
const storage::FileSystemURL& root,
const std::string& filesystem_name,
base::File::Error result);
void DidResolveURL(ResolveURLCallback callback,
base::File::Error result,
const storage::FileSystemInfo& info,
const base::FilePath& file_path,
storage::FileSystemContext::ResolvedEntryType type);
void DidCreateSnapshot(
CreateSnapshotFileCallback callback,
const storage::FileSystemURL& url,
base::File::Error result,
const base::File::Info& info,
const base::FilePath& platform_path,
scoped_refptr<storage::ShareableFileReference> file_ref);
void ContinueDidCreateSnapshot(CreateSnapshotFileCallback callback,
const storage::FileSystemURL& url,
base::File::Error result,
const base::File::Info& info,
const base::FilePath& platform_path,
bool security_check_success);
void DidGetPlatformPath(scoped_refptr<storage::FileSystemContext> context,
GetPlatformPathCallback callback,
base::FilePath platform_path);
static void GetPlatformPathOnFileThread(
const GURL& path,
int process_id,
scoped_refptr<storage::FileSystemContext> context,
base::WeakPtr<FileSystemManagerImpl> file_system_manager,
const blink::StorageKey& storage_key,
GetPlatformPathCallback callback);
// Returns an error if `url` is invalid.
std::optional<base::File::Error> ValidateFileSystemURL(
const storage::FileSystemURL& url);
storage::FileSystemOperationRunner* operation_runner() {
return operation_runner_.get();
}
OperationListenerID AddOpListener(
mojo::Remote<blink::mojom::FileSystemOperationListener> listener);
void RemoveOpListener(OperationListenerID listener_id);
blink::mojom::FileSystemOperationListener* GetOpListener(
OperationListenerID listener_id);
void OnConnectionErrorForOpListeners(OperationListenerID listener_id);
const int process_id_;
const scoped_refptr<storage::FileSystemContext> context_;
const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
std::unique_ptr<storage::FileSystemOperationRunner> operation_runner_;
mojo::ReceiverSet<blink::mojom::FileSystemManager, blink::StorageKey>
receivers_;
mojo::UniqueReceiverSet<blink::mojom::FileSystemCancellableOperation>
cancellable_operations_;
mojo::UniqueReceiverSet<blink::mojom::ReceivedSnapshotListener>
snapshot_listeners_;
std::unordered_map<OperationListenerID,
mojo::Remote<blink::mojom::FileSystemOperationListener>>
op_listeners_;
OperationListenerID next_operation_listener_id_ = 1;
// Used to keep snapshot files alive while a DidCreateSnapshot
// is being sent to the renderer.
base::IDMap<scoped_refptr<storage::ShareableFileReference>>
in_transit_snapshot_files_;
base::WeakPtrFactory<FileSystemManagerImpl> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_MANAGER_IMPL_H_