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
3 // found in the LICENSE file.
4 //
5 // This file provides file system related API functions.
6 
7 #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_
8 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <memory>
14 #include <set>
15 #include <string>
16 #include <vector>
17 
18 #include "base/callback_forward.h"
19 #include "base/macros.h"
20 #include "base/memory/weak_ptr.h"
21 #include "chrome/browser/chromeos/extensions/file_manager/file_stream_string_converter.h"
22 #include "chrome/browser/chromeos/extensions/file_manager/private_api_base.h"
23 #include "chrome/browser/extensions/chrome_extension_function_details.h"
24 #include "components/drive/file_errors.h"
25 #include "extensions/browser/extension_function.h"
26 #include "services/device/public/mojom/mtp_storage_info.mojom-forward.h"
27 #include "storage/browser/file_system/file_system_url.h"
28 
29 namespace storage {
30 class FileSystemContext;
31 class FileSystemURL;
32 class WatcherManager;
33 }  // namespace storage
34 
35 namespace file_manager {
36 class EventRouter;
37 namespace util {
38 struct EntryDefinition;
39 typedef std::vector<EntryDefinition> EntryDefinitionList;
40 }  // namespace util
41 }  // namespace file_manager
42 
43 namespace drive {
44 namespace util {
45 class FileStreamMd5Digester;
46 }  // namespace util
47 
48 // File path and its MD5 hash obtained from drive.
49 struct HashAndFilePath {
50   std::string hash;
51   base::FilePath path;
52 };
53 
54 }  // namespace drive
55 
56 namespace extensions {
57 
58 // Grant permission to request externalfile scheme. The permission is needed to
59 // start drag for external file URL.
60 class FileManagerPrivateEnableExternalFileSchemeFunction
61     : public ExtensionFunction {
62  public:
63   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.enableExternalFileScheme",
64                              FILEMANAGERPRIVATE_ENABLEEXTERNALFILESCHEME)
65 
66  protected:
67   ~FileManagerPrivateEnableExternalFileSchemeFunction() override = default;
68 
69  private:
70   ExtensionFunction::ResponseAction Run() override;
71 };
72 
73 // Grants R/W permissions to profile-specific directories (Drive, Downloads)
74 // from other profiles.
75 class FileManagerPrivateGrantAccessFunction : public ExtensionFunction {
76  public:
77   FileManagerPrivateGrantAccessFunction();
78 
79   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.grantAccess",
80                              FILEMANAGERPRIVATE_GRANTACCESS)
81 
82  protected:
83   ~FileManagerPrivateGrantAccessFunction() override = default;
84 
85  private:
86   ExtensionFunction::ResponseAction Run() override;
87   const ChromeExtensionFunctionDetails chrome_details_;
88   DISALLOW_COPY_AND_ASSIGN(FileManagerPrivateGrantAccessFunction);
89 };
90 
91 // Base class for FileManagerPrivateInternalAddFileWatchFunction and
92 // FileManagerPrivateInternalRemoveFileWatchFunction. Although it's called
93 // "FileWatch",
94 // the class and its sub classes are used only for watching changes in
95 // directories.
96 class FileWatchFunctionBase : public LoggedExtensionFunction {
97  public:
98   using ResponseCallback = base::Callback<void(bool success)>;
99 
100   // Calls Respond() with |success| converted to base::Value.
101   void RespondWith(bool success);
102 
103  protected:
104   ~FileWatchFunctionBase() override = default;
105 
106   // Performs a file watch operation (ex. adds or removes a file watch) on
107   // the IO thread with storage::WatcherManager.
108   virtual void PerformFileWatchOperationOnIOThread(
109       scoped_refptr<storage::FileSystemContext> file_system_context,
110       storage::WatcherManager* watcher_manager,
111       const storage::FileSystemURL& file_system_url,
112       base::WeakPtr<file_manager::EventRouter> event_router) = 0;
113 
114   // Performs a file watch operation (ex. adds or removes a file watch) on
115   // the UI thread with file_manager::EventRouter. This is a fallback operation
116   // called only when WatcherManager is unavailable.
117   virtual void PerformFallbackFileWatchOperationOnUIThread(
118       const storage::FileSystemURL& file_system_url,
119       base::WeakPtr<file_manager::EventRouter> event_router) = 0;
120 
121   // ExtensionFunction overrides.
122   ResponseAction Run() override;
123 
124  private:
125   void RunAsyncOnIOThread(
126       scoped_refptr<storage::FileSystemContext> file_system_context,
127       const storage::FileSystemURL& file_system_url,
128       base::WeakPtr<file_manager::EventRouter> event_router);
129 };
130 
131 // Implements the chrome.fileManagerPrivate.addFileWatch method.
132 // Starts watching changes in directories.
133 class FileManagerPrivateInternalAddFileWatchFunction
134     : public FileWatchFunctionBase {
135  public:
136   DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.addFileWatch",
137                              FILEMANAGERPRIVATEINTERNAL_ADDFILEWATCH)
138 
139  protected:
140   ~FileManagerPrivateInternalAddFileWatchFunction() override = default;
141 
142   // FileWatchFunctionBase override.
143   void PerformFileWatchOperationOnIOThread(
144       scoped_refptr<storage::FileSystemContext> file_system_context,
145       storage::WatcherManager* watcher_manager,
146       const storage::FileSystemURL& file_system_url,
147       base::WeakPtr<file_manager::EventRouter> event_router) override;
148   void PerformFallbackFileWatchOperationOnUIThread(
149       const storage::FileSystemURL& file_system_url,
150       base::WeakPtr<file_manager::EventRouter> event_router) override;
151 };
152 
153 
154 // Implements the chrome.fileManagerPrivate.removeFileWatch method.
155 // Stops watching changes in directories.
156 class FileManagerPrivateInternalRemoveFileWatchFunction
157     : public FileWatchFunctionBase {
158  public:
159   DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.removeFileWatch",
160                              FILEMANAGERPRIVATEINTERNAL_REMOVEFILEWATCH)
161 
162  protected:
163   ~FileManagerPrivateInternalRemoveFileWatchFunction() override = default;
164 
165   // FileWatchFunctionBase override.
166   void PerformFileWatchOperationOnIOThread(
167       scoped_refptr<storage::FileSystemContext> file_system_context,
168       storage::WatcherManager* watcher_manager,
169       const storage::FileSystemURL& file_system_url,
170       base::WeakPtr<file_manager::EventRouter> event_router) override;
171   void PerformFallbackFileWatchOperationOnUIThread(
172       const storage::FileSystemURL& file_system_url,
173       base::WeakPtr<file_manager::EventRouter> event_router) override;
174 };
175 
176 // Implements the chrome.fileManagerPrivate.getSizeStats method.
177 class FileManagerPrivateGetSizeStatsFunction : public LoggedExtensionFunction {
178  public:
179   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getSizeStats",
180                              FILEMANAGERPRIVATE_GETSIZESTATS)
181 
182  protected:
183   ~FileManagerPrivateGetSizeStatsFunction() override = default;
184 
185   // ExtensionFunction overrides.
186   ResponseAction Run() override;
187 
188  private:
189   void OnGetDriveAvailableSpace(drive::FileError error,
190                                 int64_t bytes_total,
191                                 int64_t bytes_used);
192 
193   void OnGetMtpAvailableSpace(device::mojom::MtpStorageInfoPtr mtp_storage_info,
194                               const bool error);
195 
196   void OnGetSizeStats(const uint64_t* total_size,
197                       const uint64_t* remaining_size);
198 };
199 
200 // Implements the chrome.fileManagerPrivate.validatePathNameLength method.
201 class FileManagerPrivateInternalValidatePathNameLengthFunction
202     : public LoggedExtensionFunction {
203  public:
204   DECLARE_EXTENSION_FUNCTION(
205       "fileManagerPrivateInternal.validatePathNameLength",
206       FILEMANAGERPRIVATEINTERNAL_VALIDATEPATHNAMELENGTH)
207 
208  protected:
209   ~FileManagerPrivateInternalValidatePathNameLengthFunction() override =
210       default;
211 
212   void OnFilePathLimitRetrieved(size_t current_length, size_t max_length);
213 
214   // ExtensionFunction overrides.
215   ResponseAction Run() override;
216 };
217 
218 // Implements the chrome.fileManagerPrivate.formatVolume method.
219 // Formats Volume given its mount path.
220 class FileManagerPrivateFormatVolumeFunction : public LoggedExtensionFunction {
221  public:
222   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.formatVolume",
223                              FILEMANAGERPRIVATE_FORMATVOLUME)
224 
225  protected:
226   ~FileManagerPrivateFormatVolumeFunction() override = default;
227 
228   // ExtensionFunction overrides.
229   ResponseAction Run() override;
230 };
231 
232 // Implements the chrome.fileManagerPrivate.singlePartitionFormat method.
233 // Deletes removable device partitions, create a single partition and format.
234 class FileManagerPrivateSinglePartitionFormatFunction
235     : public LoggedExtensionFunction {
236  public:
237   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.singlePartitionFormat",
238                              FILEMANAGERPRIVATE_SINGLEPARTITIONFORMAT)
239 
240  protected:
241   ~FileManagerPrivateSinglePartitionFormatFunction() override = default;
242 
243   // ExtensionFunction overrides.
244   ResponseAction Run() override;
245 };
246 
247 // Implements the chrome.fileManagerPrivate.renameVolume method.
248 // Renames Volume given its mount path and new Volume name.
249 class FileManagerPrivateRenameVolumeFunction : public LoggedExtensionFunction {
250  public:
251   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.renameVolume",
252                              FILEMANAGERPRIVATE_RENAMEVOLUME)
253 
254  protected:
255   ~FileManagerPrivateRenameVolumeFunction() override = default;
256 
257   // ExtensionFunction overrides.
258   ResponseAction Run() override;
259 };
260 
261 // Implements the chrome.fileManagerPrivateInternal.copyImageToClipboard method.
262 class FileManagerPrivateInternalCopyImageToClipboardFunction
263     : public LoggedExtensionFunction {
264  public:
265   FileManagerPrivateInternalCopyImageToClipboardFunction();
266 
267   DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.copyImageToClipboard",
268                              FILEMANAGERPRIVATEINTERNAL_COPYIMAGETOCLIPBOARD)
269 
270  protected:
271   ~FileManagerPrivateInternalCopyImageToClipboardFunction() override;
272 
273   // ExtensionFunction overrides.
274   ResponseAction Run() override;
275 
276  private:
277   // `is_on_clipboard` specifies whether or not the image was copied to the
278   // clipboard.
279   void RespondWith(bool is_on_clipboard);
280   void MoveBytesToClipboard(scoped_refptr<base::RefCountedString> bytes);
281 
282   const ChromeExtensionFunctionDetails chrome_details_;
283   std::unique_ptr<storage::FileStreamStringConverter> converter_;
284   // Stores the clipboard copy sequence number to validate the clipboard did not
285   // change during an async operation.
286   uint64_t clipboard_sequence_ = 0;
287 };
288 
289 // Implements the chrome.fileManagerPrivate.startCopy method.
290 class FileManagerPrivateInternalStartCopyFunction
291     : public LoggedExtensionFunction {
292  public:
293   FileManagerPrivateInternalStartCopyFunction();
294 
295   DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.startCopy",
296                              FILEMANAGERPRIVATEINTERNAL_STARTCOPY)
297 
298  protected:
299   ~FileManagerPrivateInternalStartCopyFunction() override = default;
300 
301   // ExtensionFunction overrides.
302   ResponseAction Run() override;
303 
304  private:
305   void RunAfterGetFileMetadata(base::File::Error result,
306                                const base::File::Info& file_info);
307 
308   // Part of RunAsync(). Called after the amount of space on the destination
309   // is known.
310   void RunAfterCheckDiskSpace(int64_t space_needed,
311                               const std::vector<int64_t>& spaces_available);
312 
313   // Part of RunAsync(). Called after FreeDiskSpaceIfNeededFor() is completed on
314   // IO thread.
315   void RunAfterFreeDiskSpace(bool available);
316 
317   // Part of RunAsync(). Called after Copy() is started on IO thread.
318   void RunAfterStartCopy(int operation_id);
319 
320   storage::FileSystemURL source_url_;
321   storage::FileSystemURL destination_url_;
322   const ChromeExtensionFunctionDetails chrome_details_;
323 };
324 
325 // Implements the chrome.fileManagerPrivate.cancelCopy method.
326 class FileManagerPrivateCancelCopyFunction : public LoggedExtensionFunction {
327  public:
328   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.cancelCopy",
329                              FILEMANAGERPRIVATE_CANCELCOPY)
330 
331  protected:
332   ~FileManagerPrivateCancelCopyFunction() override = default;
333 
334   // ExtensionFunction overrides.
335   ResponseAction Run() override;
336 };
337 
338 // Implements the chrome.fileManagerPrivateInternal.resolveIsolatedEntries
339 // method.
340 class FileManagerPrivateInternalResolveIsolatedEntriesFunction
341     : public LoggedExtensionFunction {
342  public:
343   DECLARE_EXTENSION_FUNCTION(
344       "fileManagerPrivateInternal.resolveIsolatedEntries",
345       FILEMANAGERPRIVATE_RESOLVEISOLATEDENTRIES)
346 
347  protected:
348   ~FileManagerPrivateInternalResolveIsolatedEntriesFunction() override =
349       default;
350 
351   // ExtensionFunction overrides.
352   ResponseAction Run() override;
353 
354  private:
355   void RunAsyncAfterConvertFileDefinitionListToEntryDefinitionList(
356       std::unique_ptr<file_manager::util::EntryDefinitionList>
357           entry_definition_list);
358 };
359 
360 class FileManagerPrivateInternalComputeChecksumFunction
361     : public LoggedExtensionFunction {
362  public:
363   FileManagerPrivateInternalComputeChecksumFunction();
364 
365   DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.computeChecksum",
366                              FILEMANAGERPRIVATEINTERNAL_COMPUTECHECKSUM)
367 
368  protected:
369   ~FileManagerPrivateInternalComputeChecksumFunction() override;
370 
371   // ExtensionFunction overrides.
372   ResponseAction Run() override;
373 
374  private:
375   std::unique_ptr<drive::util::FileStreamMd5Digester> digester_;
376 
377   void RespondWith(std::string hash);
378 };
379 
380 // Implements the chrome.fileManagerPrivate.searchFilesByHashes method.
381 class FileManagerPrivateSearchFilesByHashesFunction
382     : public LoggedExtensionFunction {
383  public:
384   FileManagerPrivateSearchFilesByHashesFunction();
385 
386   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.searchFilesByHashes",
387                              FILEMANAGERPRIVATE_SEARCHFILESBYHASHES)
388 
389  protected:
390   ~FileManagerPrivateSearchFilesByHashesFunction() override = default;
391 
392  private:
393   // ExtensionFunction overrides.
394   ResponseAction Run() override;
395 
396   // Fallback to walking the filesystem and checking file attributes.
397   std::vector<drive::HashAndFilePath> SearchByAttribute(
398       const std::set<std::string>& hashes,
399       const base::FilePath& dir,
400       const base::FilePath& prefix);
401   void OnSearchByAttribute(const std::set<std::string>& hashes,
402                            const std::vector<drive::HashAndFilePath>& results);
403 
404   // Sends a response with |results| to the extension.
405   void OnSearchByHashes(const std::set<std::string>& hashes,
406                         drive::FileError error,
407                         const std::vector<drive::HashAndFilePath>& results);
408 
409   const ChromeExtensionFunctionDetails chrome_details_;
410 };
411 
412 class FileManagerPrivateSearchFilesFunction : public LoggedExtensionFunction {
413  public:
414   FileManagerPrivateSearchFilesFunction();
415 
416   DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.searchFiles",
417                              FILEMANAGERPRIVATE_SEARCHFILES)
418 
419  protected:
420   ~FileManagerPrivateSearchFilesFunction() override = default;
421 
422  private:
423   // ExtensionFunction overrides.
424   ResponseAction Run() override;
425 
426   void OnSearchByPattern(
427       const std::vector<std::pair<base::FilePath, bool>>& results);
428 
429   const ChromeExtensionFunctionDetails chrome_details_;
430 };
431 
432 // Implements the chrome.fileManagerPrivate.getDirectorySize method.
433 class FileManagerPrivateInternalGetDirectorySizeFunction
434     : public LoggedExtensionFunction {
435  public:
436   DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.getDirectorySize",
437                              FILEMANAGERPRIVATEINTERNAL_GETDIRECTORYSIZE)
438 
439  protected:
440   ~FileManagerPrivateInternalGetDirectorySizeFunction() override = default;
441 
442   void OnDirectorySizeRetrieved(int64_t size);
443 
444   // ExtensionFunction overrides
445   ResponseAction Run() override;
446 };
447 
448 }  // namespace extensions
449 
450 #endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_
451