1 // Copyright (c) 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 #ifndef CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_MANAGER_IMPL_H_
6 #define CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_MANAGER_IMPL_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <unordered_map>
15 #include <vector>
16 
17 #include "base/callback.h"
18 #include "base/macros.h"
19 #include "base/memory/ref_counted.h"
20 #include "components/services/filesystem/public/mojom/types.mojom.h"
21 #include "content/common/content_export.h"
22 #include "content/public/browser/browser_message_filter.h"
23 #include "mojo/public/cpp/bindings/pending_receiver.h"
24 #include "mojo/public/cpp/bindings/pending_remote.h"
25 #include "mojo/public/cpp/bindings/receiver_set.h"
26 #include "mojo/public/cpp/bindings/unique_receiver_set.h"
27 #include "storage/browser/file_system/file_system_context.h"
28 #include "storage/browser/file_system/file_system_operation_runner.h"
29 #include "storage/common/file_system/file_system_types.h"
30 #include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
31 
32 class GURL;
33 
34 namespace base {
35 class FilePath;
36 }  // namespace base
37 
38 namespace storage {
39 class FileSystemURL;
40 class FileSystemOperationRunner;
41 struct FileSystemInfo;
42 class ShareableFileReference;
43 }  // namespace storage
44 
45 namespace content {
46 class ChildProcessSecurityPolicyImpl;
47 class ChromeBlobStorageContext;
48 
49 // All methods for this class are expected to be called on the IO thread,
50 // except for the constructor. The destructor must also be called on the IO
51 // thread as weak refs are created on that thread. A single instance of this
52 // class is owned by RenderProcessHostImpl.
53 class CONTENT_EXPORT FileSystemManagerImpl
54     : public blink::mojom::FileSystemManager {
55  public:
56   // Constructed and held by the render frame host and render process host on
57   // the UI thread. Used by render frames (via the render frame host), workers
58   // and pepper (via the render process host).
59   FileSystemManagerImpl(
60       int process_id,
61       scoped_refptr<storage::FileSystemContext> file_system_context,
62       scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
63   ~FileSystemManagerImpl() override;
64   base::WeakPtr<FileSystemManagerImpl> GetWeakPtr();
65 
66   void BindReceiver(
67       mojo::PendingReceiver<blink::mojom::FileSystemManager> receiver);
68 
69   // blink::mojom::FileSystem
70   void Open(const url::Origin& origin,
71             blink::mojom::FileSystemType file_system_type,
72             OpenCallback callback) override;
73   void ResolveURL(const GURL& filesystem_url,
74                   ResolveURLCallback callback) override;
75   void Move(const GURL& src_path,
76             const GURL& dest_path,
77             MoveCallback callback) override;
78   void Copy(const GURL& src_path,
79             const GURL& dest_path,
80             CopyCallback callback) override;
81   void Remove(const GURL& path,
82               bool recursive,
83               RemoveCallback callback) override;
84   void ReadMetadata(const GURL& path, ReadMetadataCallback callback) override;
85   void Create(const GURL& path,
86               bool exclusive,
87               bool is_directory,
88               bool recursive,
89               CreateCallback callback) override;
90   void Exists(const GURL& path,
91               bool is_directory,
92               ExistsCallback callback) override;
93   void ReadDirectory(
94       const GURL& path,
95       mojo::PendingRemote<blink::mojom::FileSystemOperationListener>
96           pending_listener) override;
97   void ReadDirectorySync(const GURL& path,
98                          ReadDirectorySyncCallback callback) override;
99   void Write(const GURL& file_path,
100              const std::string& blob_uuid,
101              int64_t position,
102              mojo::PendingReceiver<blink::mojom::FileSystemCancellableOperation>
103                  op_receiver,
104              mojo::PendingRemote<blink::mojom::FileSystemOperationListener>
105                  pending_listener) override;
106   void WriteSync(const GURL& file_path,
107                  const std::string& blob_uuid,
108                  int64_t position,
109                  WriteSyncCallback callback) override;
110   void Truncate(
111       const GURL& file_path,
112       int64_t length,
113       mojo::PendingReceiver<blink::mojom::FileSystemCancellableOperation>
114           op_receiver,
115       TruncateCallback callback) override;
116   void TruncateSync(const GURL& file_path,
117                     int64_t length,
118                     TruncateSyncCallback callback) override;
119   void CreateSnapshotFile(const GURL& file_path,
120                           CreateSnapshotFileCallback callback) override;
121   void GetPlatformPath(const GURL& file_path,
122                        GetPlatformPathCallback callback) override;
123 
124  private:
125   class FileSystemCancellableOperationImpl;
126   class ReceivedSnapshotListenerImpl;
127   using OperationID = storage::FileSystemOperationRunner::OperationID;
128   using OperationListenerID = int;
129   struct WriteSyncCallbackEntry;
130   struct ReadDirectorySyncCallbackEntry;
131 
132   void Cancel(
133       OperationID op_id,
134       blink::mojom::FileSystemCancellableOperation::CancelCallback callback);
135   void DidReceiveSnapshotFile(int snapshot_id);
136   void OnConnectionError();
137 
138   // Callback functions to be used when each file operation is finished.
139   void DidFinish(base::OnceCallback<void(base::File::Error)> callback,
140                  base::File::Error error_code);
141   void DidGetMetadata(ReadMetadataCallback callback,
142                       base::File::Error result,
143                       const base::File::Info& info);
144   void DidGetMetadataForStreaming(CreateSnapshotFileCallback callback,
145                                   base::File::Error result,
146                                   const base::File::Info& info);
147   void DidReadDirectory(OperationListenerID listener_id,
148                         base::File::Error result,
149                         std::vector<filesystem::mojom::DirectoryEntry> entries,
150                         bool has_more);
151   void DidReadDirectorySync(
152       ReadDirectorySyncCallbackEntry* callback_entry,
153       base::File::Error result,
154       std::vector<filesystem::mojom::DirectoryEntry> entries,
155       bool has_more);
156   void DidWrite(OperationListenerID listener_id,
157                 base::File::Error result,
158                 int64_t bytes,
159                 bool complete);
160   void DidWriteSync(WriteSyncCallbackEntry* entry,
161                     base::File::Error result,
162                     int64_t bytes,
163                     bool complete);
164   void DidOpenFileSystem(OpenCallback callback,
165                          const GURL& root,
166                          const std::string& filesystem_name,
167                          base::File::Error result);
168   void DidResolveURL(ResolveURLCallback callback,
169                      base::File::Error result,
170                      const storage::FileSystemInfo& info,
171                      const base::FilePath& file_path,
172                      storage::FileSystemContext::ResolvedEntryType type);
173   void DidCreateSnapshot(
174       CreateSnapshotFileCallback callback,
175       const storage::FileSystemURL& url,
176       base::File::Error result,
177       const base::File::Info& info,
178       const base::FilePath& platform_path,
179       scoped_refptr<storage::ShareableFileReference> file_ref);
180   void DidGetPlatformPath(GetPlatformPathCallback callback,
181                           base::FilePath platform_path);
182 
183   static void GetPlatformPathOnFileThread(
184       const GURL& path,
185       int process_id,
186       scoped_refptr<storage::FileSystemContext> context,
187       base::WeakPtr<FileSystemManagerImpl> file_system_manager,
188       GetPlatformPathCallback callback);
189   // Returns an error if |url| is invalid.
190   base::Optional<base::File::Error> ValidateFileSystemURL(
191       const storage::FileSystemURL& url);
192 
operation_runner()193   storage::FileSystemOperationRunner* operation_runner() {
194     return operation_runner_.get();
195   }
196 
197   OperationListenerID AddOpListener(
198       mojo::Remote<blink::mojom::FileSystemOperationListener> listener);
199   void RemoveOpListener(OperationListenerID listener_id);
200   blink::mojom::FileSystemOperationListener* GetOpListener(
201       OperationListenerID listener_id);
202   void OnConnectionErrorForOpListeners(OperationListenerID listener_id);
203 
204   const int process_id_;
205   const scoped_refptr<storage::FileSystemContext> context_;
206   ChildProcessSecurityPolicyImpl* const security_policy_;
207   const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
208   std::unique_ptr<storage::FileSystemOperationRunner> operation_runner_;
209 
210   mojo::ReceiverSet<blink::mojom::FileSystemManager> receivers_;
211   mojo::UniqueReceiverSet<blink::mojom::FileSystemCancellableOperation>
212       cancellable_operations_;
213   mojo::UniqueReceiverSet<blink::mojom::ReceivedSnapshotListener>
214       snapshot_listeners_;
215 
216   std::unordered_map<OperationListenerID,
217                      mojo::Remote<blink::mojom::FileSystemOperationListener>>
218       op_listeners_;
219   OperationListenerID next_operation_listener_id_ = 1;
220 
221   // Used to keep snapshot files alive while a DidCreateSnapshot
222   // is being sent to the renderer.
223   base::IDMap<scoped_refptr<storage::ShareableFileReference>>
224       in_transit_snapshot_files_;
225 
226   base::WeakPtrFactory<FileSystemManagerImpl> weak_factory_{this};
227 
228   DISALLOW_COPY_AND_ASSIGN(FileSystemManagerImpl);
229 };
230 
231 }  // namespace content
232 
233 #endif  // CONTENT_BROWSER_FILE_SYSTEM_FILE_SYSTEM_MANAGER_IMPL_H_
234