1 // Copyright 2014 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 CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
6 #define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "base/callback.h"
16 #include "base/files/file.h"
17 #include "base/files/file_path.h"
18 #include "base/macros.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/observer_list.h"
21 #include "chrome/browser/chromeos/file_system_provider/abort_callback.h"
22 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_observer.h"
23 #include "chrome/browser/chromeos/file_system_provider/watcher.h"
24 #include "storage/browser/file_system/async_file_util.h"
25 #include "storage/browser/file_system/watcher_manager.h"
26 #include "url/gurl.h"
27 
28 namespace base {
29 class Time;
30 }  // namespace base
31 
32 namespace net {
33 class IOBuffer;
34 }  // namespace net
35 
36 namespace chromeos {
37 namespace file_system_provider {
38 
39 class ProvidedFileSystemInfo;
40 class RequestManager;
41 
42 // Represents metadata for either a file or a directory.
43 struct EntryMetadata {
44   EntryMetadata();
45   ~EntryMetadata();
46 
47   // All of the metadata fields are optional. All strings which are set, are
48   // non-empty.
49   std::unique_ptr<bool> is_directory;
50   std::unique_ptr<std::string> name;
51   std::unique_ptr<int64_t> size;
52   std::unique_ptr<base::Time> modification_time;
53   std::unique_ptr<std::string> mime_type;
54   std::unique_ptr<std::string> thumbnail;
55 
56  private:
57   DISALLOW_COPY_AND_ASSIGN(EntryMetadata);
58 };
59 
60 // Represents actions for either a file or a directory.
61 struct Action {
62   std::string id;
63   std::string title;
64 };
65 
66 typedef std::vector<Action> Actions;
67 
68 // Mode of opening a file. Used by OpenFile().
69 enum OpenFileMode { OPEN_FILE_MODE_READ, OPEN_FILE_MODE_WRITE };
70 
71 // Contains information about an opened file.
72 struct OpenedFile {
73   OpenedFile(const base::FilePath& file_path, OpenFileMode mode);
74   OpenedFile();
75   ~OpenedFile();
76 
77   base::FilePath file_path;
78   OpenFileMode mode;
79 };
80 
81 // Map from a file handle to an OpenedFile struct.
82 typedef std::map<int, OpenedFile> OpenedFiles;
83 
84 // Interface for a provided file system. Acts as a proxy between providers
85 // and clients. All of the request methods return an abort callback in order to
86 // terminate it while running. They must be called on the same thread as the
87 // request methods. The cancellation callback may be null if the operation
88 // fails synchronously. It must not be called once the operation is completed
89 // with either a success or an error.
90 class ProvidedFileSystemInterface {
91  public:
92   // Fields to be fetched with metadata.
93   enum MetadataField {
94     METADATA_FIELD_NONE = 0,
95     METADATA_FIELD_IS_DIRECTORY = 1 << 0,
96     METADATA_FIELD_NAME = 1 << 1,
97     METADATA_FIELD_SIZE = 1 << 2,
98     METADATA_FIELD_MODIFICATION_TIME = 1 << 3,
99     METADATA_FIELD_MIME_TYPE = 1 << 4,
100     METADATA_FIELD_THUMBNAIL = 1 << 5
101   };
102 
103   // Callback for OpenFile(). In case of an error, file_handle is equal to 0
104   // and result is set to an error code.
105   typedef base::OnceCallback<void(int file_handle, base::File::Error result)>
106       OpenFileCallback;
107 
108   typedef base::RepeatingCallback<
109       void(int chunk_length, bool has_more, base::File::Error result)>
110       ReadChunkReceivedCallback;
111 
112   typedef base::OnceCallback<void(std::unique_ptr<EntryMetadata> entry_metadata,
113                                   base::File::Error result)>
114       GetMetadataCallback;
115 
116   typedef base::OnceCallback<void(const Actions& actions,
117                                   base::File::Error result)>
118       GetActionsCallback;
119 
120   // Mask of fields requested from the GetMetadata() call.
121   typedef int MetadataFieldMask;
122 
~ProvidedFileSystemInterface()123   virtual ~ProvidedFileSystemInterface() {}
124 
125   // Requests unmounting of the file system. The callback is called when the
126   // request is accepted or rejected, with an error code.
127   virtual AbortCallback RequestUnmount(
128       storage::AsyncFileUtil::StatusCallback callback) = 0;
129 
130   // Requests metadata of the passed |entry_path|. It can be either a file
131   // or a directory. All |fields| will be returned if supported. Note, that
132   // default fields are always returned.
133   virtual AbortCallback GetMetadata(const base::FilePath& entry_path,
134                                     MetadataFieldMask fields,
135                                     GetMetadataCallback callback) = 0;
136 
137   // Requests list of actions for the passed list of entries at |entry_paths|.
138   // They can be either files or directories.
139   virtual AbortCallback GetActions(
140       const std::vector<base::FilePath>& entry_paths,
141       GetActionsCallback callback) = 0;
142 
143   // Executes the |action_id| action on the list of entries at |entry_paths|.
144   virtual AbortCallback ExecuteAction(
145       const std::vector<base::FilePath>& entry_paths,
146       const std::string& action_id,
147       storage::AsyncFileUtil::StatusCallback callback) = 0;
148 
149   // Requests enumerating entries from the passed |directory_path|. The callback
150   // can be called multiple times until |has_more| is set to false.
151   virtual AbortCallback ReadDirectory(
152       const base::FilePath& directory_path,
153       storage::AsyncFileUtil::ReadDirectoryCallback callback) = 0;
154 
155   // Requests opening a file at |file_path|. If the file doesn't exist, then the
156   // operation will fail. In case of any error, the returned file handle is 0.
157   virtual AbortCallback OpenFile(const base::FilePath& file_path,
158                                  OpenFileMode mode,
159                                  OpenFileCallback callback) = 0;
160 
161   // Requests closing a file, previously opened with OpenFile() as a file with
162   // |file_handle|. The |callback| must be called.
163   virtual AbortCallback CloseFile(
164       int file_handle,
165       storage::AsyncFileUtil::StatusCallback callback) = 0;
166 
167   // Requests reading a file previously opened with |file_handle|. The callback
168   // can be called multiple times until |has_more| is set to false. On success
169   // it should return |length| bytes starting from |offset| in total. It can
170   // return less only in case EOF is encountered.
171   virtual AbortCallback ReadFile(int file_handle,
172                                  net::IOBuffer* buffer,
173                                  int64_t offset,
174                                  int length,
175                                  ReadChunkReceivedCallback callback) = 0;
176 
177   // Requests creating a directory. If |recursive| is passed, then all non
178   // existing directories on the path will be created. The operation will fail
179   // if the target directory already exists.
180   virtual AbortCallback CreateDirectory(
181       const base::FilePath& directory_path,
182       bool recursive,
183       storage::AsyncFileUtil::StatusCallback callback) = 0;
184 
185   // Requests creating a file. If the entry already exists, then the
186   // FILE_ERROR_EXISTS error must be returned.
187   virtual AbortCallback CreateFile(
188       const base::FilePath& file_path,
189       storage::AsyncFileUtil::StatusCallback callback) = 0;
190 
191   // Requests deleting a directory. If |recursive| is passed and the entry is
192   // a directory, then all contents of it (recursively) will be deleted too.
193   virtual AbortCallback DeleteEntry(
194       const base::FilePath& entry_path,
195       bool recursive,
196       storage::AsyncFileUtil::StatusCallback callback) = 0;
197 
198   // Requests copying an entry (recursively in case of a directory) within the
199   // same file system.
200   virtual AbortCallback CopyEntry(
201       const base::FilePath& source_path,
202       const base::FilePath& target_path,
203       storage::AsyncFileUtil::StatusCallback callback) = 0;
204 
205   // Requests moving an entry (recursively in case of a directory) within the
206   // same file system.
207   virtual AbortCallback MoveEntry(
208       const base::FilePath& source_path,
209       const base::FilePath& target_path,
210       storage::AsyncFileUtil::StatusCallback callback) = 0;
211 
212   // Requests truncating a file to the desired length.
213   virtual AbortCallback Truncate(
214       const base::FilePath& file_path,
215       int64_t length,
216       storage::AsyncFileUtil::StatusCallback callback) = 0;
217 
218   // Requests writing to a file previously opened with |file_handle|.
219   virtual AbortCallback WriteFile(
220       int file_handle,
221       net::IOBuffer* buffer,
222       int64_t offset,
223       int length,
224       storage::AsyncFileUtil::StatusCallback callback) = 0;
225 
226   // Requests adding a watcher on an entry. |recursive| must not be true for
227   // files. |callback| is optional, but it can't be used for persistent
228   // watchers.
229   virtual AbortCallback AddWatcher(
230       const GURL& origin,
231       const base::FilePath& entry_path,
232       bool recursive,
233       bool persistent,
234       storage::AsyncFileUtil::StatusCallback callback,
235       storage::WatcherManager::NotificationCallback notification_callback) = 0;
236 
237   // Requests removing a watcher, which is immediately deleted from the internal
238   // list, hence the operation is not abortable.
239   virtual void RemoveWatcher(
240       const GURL& origin,
241       const base::FilePath& entry_path,
242       bool recursive,
243       storage::AsyncFileUtil::StatusCallback callback) = 0;
244 
245   // Notifies about changes related to the watcher within the file system.
246   // Invoked by the file system implementation. Returns an error code via the
247   // callback if the notification arguments are malformed or the entry is not
248   // watched anymore. On success, returns base::File::FILE_OK.
249   // TODO(mtomasz): Replace [entry_path, recursive] with a watcher id.
250   virtual void Notify(
251       const base::FilePath& entry_path,
252       bool recursive,
253       storage::WatcherManager::ChangeType change_type,
254       std::unique_ptr<ProvidedFileSystemObserver::Changes> changes,
255       const std::string& tag,
256       storage::AsyncFileUtil::StatusCallback callback) = 0;
257 
258   // Requests showing UI for configuring the file system by user. Once the
259   // configuration process is completed, base::File::FILE_OK or an error code is
260   // returned via the |callback|.
261   virtual void Configure(storage::AsyncFileUtil::StatusCallback callback) = 0;
262 
263   // Returns a provided file system info for this file system.
264   virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const = 0;
265 
266   // Returns a mutable list of watchers.
267   virtual Watchers* GetWatchers() = 0;
268 
269   // Returns a list of opened files.
270   virtual const OpenedFiles& GetOpenedFiles() const = 0;
271 
272   // Returns a request manager for the file system.
273   virtual RequestManager* GetRequestManager() = 0;
274 
275   // Adds an observer on the file system.
276   virtual void AddObserver(ProvidedFileSystemObserver* observer) = 0;
277 
278   // Removes an observer.
279   virtual void RemoveObserver(ProvidedFileSystemObserver* observer) = 0;
280 
281   // Returns a weak pointer to this object.
282   virtual base::WeakPtr<ProvidedFileSystemInterface> GetWeakPtr() = 0;
283 };
284 
285 }  // namespace file_system_provider
286 }  // namespace chromeos
287 
288 #endif  // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
289