Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / file_system / file_system_api.h
blob6a2ca2cddd81477c5ccbc46417615da76a41d075
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_FILE_SYSTEM_FILE_SYSTEM_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_FILE_SYSTEM_FILE_SYSTEM_API_H_
8 #include <string>
9 #include <vector>
11 #include "base/files/file.h"
12 #include "base/files/file_path.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "chrome/browser/extensions/chrome_extension_function.h"
16 #include "chrome/browser/extensions/chrome_extension_function_details.h"
17 #include "chrome/common/extensions/api/file_system.h"
18 #include "extensions/browser/extension_function.h"
19 #include "ui/base/ui_base_types.h"
20 #include "ui/shell_dialogs/select_file_dialog.h"
22 #if defined(OS_CHROMEOS)
23 namespace file_manager {
24 class Volume;
25 } // namespace file_manager
26 #endif
28 namespace extensions {
29 class ExtensionPrefs;
30 class ScopedSkipRequestFileSystemDialog;
32 namespace file_system_api {
34 // Methods to get and set the path of the directory containing the last file
35 // chosen by the user in response to a chrome.fileSystem.chooseEntry() call for
36 // the given extension.
38 // Returns an empty path on failure.
39 base::FilePath GetLastChooseEntryDirectory(const ExtensionPrefs* prefs,
40 const std::string& extension_id);
42 void SetLastChooseEntryDirectory(ExtensionPrefs* prefs,
43 const std::string& extension_id,
44 const base::FilePath& path);
46 std::vector<base::FilePath> GetGrayListedDirectories();
48 #if defined(OS_CHROMEOS)
49 // Dispatches an event about a mounted on unmounted volume in the system to
50 // each extension which can request it.
51 void DispatchVolumeListChangeEvent(Profile* profile);
53 // Requests consent for the chrome.fileSystem.requestFileSystem() method.
54 // Interaction with UI and environmental checks (kiosk mode, whitelist) are
55 // provided by a delegate: ConsentProviderDelegate. For testing, it is
56 // TestingConsentProviderDelegate.
57 class ConsentProvider {
58 public:
59 enum Consent { CONSENT_GRANTED, CONSENT_REJECTED, CONSENT_IMPOSSIBLE };
60 typedef base::Callback<void(Consent)> ConsentCallback;
61 typedef base::Callback<void(ui::DialogButton)> ShowDialogCallback;
63 // Interface for delegating user interaction for granting permissions.
64 class DelegateInterface {
65 public:
66 // Shows a dialog for granting permissions.
67 virtual void ShowDialog(const Extension& extension,
68 const base::WeakPtr<file_manager::Volume>& volume,
69 bool writable,
70 const ShowDialogCallback& callback) = 0;
72 // Shows a notification about permissions automatically granted access.
73 virtual void ShowNotification(
74 const Extension& extension,
75 const base::WeakPtr<file_manager::Volume>& volume,
76 bool writable) = 0;
78 // Checks if the extension was launched in auto-launch kiosk mode.
79 virtual bool IsAutoLaunched(const Extension& extension) = 0;
81 // Checks if the extension is a whitelisted component extension or app.
82 virtual bool IsWhitelistedComponent(const Extension& extension) = 0;
85 explicit ConsentProvider(DelegateInterface* delegate);
86 ~ConsentProvider();
88 // Requests consent for granting |writable| permissions to the |volume|
89 // volume by the |extension|. Must be called only if the extension is
90 // grantable, which can be checked with IsGrantable().
91 void RequestConsent(const Extension& extension,
92 const base::WeakPtr<file_manager::Volume>& volume,
93 bool writable,
94 const ConsentCallback& callback);
96 // Checks whether the |extension| can be granted access.
97 bool IsGrantable(const Extension& extension);
99 private:
100 DelegateInterface* const delegate_;
102 // Converts the clicked button to a consent result and passes it via the
103 // |callback|.
104 void DialogResultToConsent(const ConsentCallback& callback,
105 ui::DialogButton button);
107 DISALLOW_COPY_AND_ASSIGN(ConsentProvider);
110 // Handles interaction with user as well as environment checks (whitelists,
111 // context of running extensions) for ConsentProvider.
112 class ConsentProviderDelegate : public ConsentProvider::DelegateInterface {
113 public:
114 ConsentProviderDelegate(Profile* profile, content::RenderFrameHost* host);
115 ~ConsentProviderDelegate();
117 private:
118 friend ScopedSkipRequestFileSystemDialog;
120 // Sets a fake result for the user consent dialog. If ui::DIALOG_BUTTON_NONE
121 // then disabled.
122 static void SetAutoDialogButtonForTest(ui::DialogButton button);
124 // ConsentProvider::DelegateInterface overrides:
125 void ShowDialog(const Extension& extension,
126 const base::WeakPtr<file_manager::Volume>& volume,
127 bool writable,
128 const file_system_api::ConsentProvider::ShowDialogCallback&
129 callback) override;
130 void ShowNotification(const Extension& extension,
131 const base::WeakPtr<file_manager::Volume>& volume,
132 bool writable) override;
133 bool IsAutoLaunched(const Extension& extension) override;
134 bool IsWhitelistedComponent(const Extension& extension) override;
136 Profile* const profile_;
137 content::RenderFrameHost* const host_;
139 DISALLOW_COPY_AND_ASSIGN(ConsentProviderDelegate);
141 #endif
143 } // namespace file_system_api
145 class FileSystemGetDisplayPathFunction : public ChromeSyncExtensionFunction {
146 public:
147 DECLARE_EXTENSION_FUNCTION("fileSystem.getDisplayPath",
148 FILESYSTEM_GETDISPLAYPATH)
150 protected:
151 ~FileSystemGetDisplayPathFunction() override {}
152 bool RunSync() override;
155 class FileSystemEntryFunction : public ChromeAsyncExtensionFunction {
156 protected:
157 FileSystemEntryFunction();
159 ~FileSystemEntryFunction() override {}
161 // This is called when writable file entries are being returned. The function
162 // will ensure the files exist, creating them if necessary, and also check
163 // that none of the files are links. If it succeeds it proceeds to
164 // RegisterFileSystemsAndSendResponse, otherwise to HandleWritableFileError.
165 void PrepareFilesForWritableApp(const std::vector<base::FilePath>& path);
167 // This will finish the choose file process. This is either called directly
168 // from FilesSelected, or from WritableFileChecker. It is called on the UI
169 // thread.
170 void RegisterFileSystemsAndSendResponse(
171 const std::vector<base::FilePath>& path);
173 // Creates a response dictionary and sets it as the response to be sent.
174 void CreateResponse();
176 // Adds an entry to the response dictionary.
177 void AddEntryToResponse(const base::FilePath& path,
178 const std::string& id_override);
180 // called on the UI thread if there is a problem checking a writable file.
181 void HandleWritableFileError(const base::FilePath& error_path);
183 // Whether multiple entries have been requested.
184 bool multiple_;
186 // Whether a directory has been requested.
187 bool is_directory_;
189 // The dictionary to send as the response.
190 base::DictionaryValue* response_;
193 class FileSystemGetWritableEntryFunction : public FileSystemEntryFunction {
194 public:
195 DECLARE_EXTENSION_FUNCTION("fileSystem.getWritableEntry",
196 FILESYSTEM_GETWRITABLEENTRY)
198 protected:
199 ~FileSystemGetWritableEntryFunction() override {}
200 bool RunAsync() override;
202 private:
203 void CheckPermissionAndSendResponse();
204 void SetIsDirectoryOnFileThread();
206 // The path to the file for which a writable entry has been requested.
207 base::FilePath path_;
210 class FileSystemIsWritableEntryFunction : public ChromeSyncExtensionFunction {
211 public:
212 DECLARE_EXTENSION_FUNCTION("fileSystem.isWritableEntry",
213 FILESYSTEM_ISWRITABLEENTRY)
215 protected:
216 ~FileSystemIsWritableEntryFunction() override {}
217 bool RunSync() override;
220 class FileSystemChooseEntryFunction : public FileSystemEntryFunction {
221 public:
222 // Allow picker UI to be skipped in testing.
223 static void SkipPickerAndAlwaysSelectPathForTest(base::FilePath* path);
224 static void SkipPickerAndAlwaysSelectPathsForTest(
225 std::vector<base::FilePath>* paths);
226 static void SkipPickerAndSelectSuggestedPathForTest();
227 static void SkipPickerAndAlwaysCancelForTest();
228 static void StopSkippingPickerForTest();
229 // Allow directory access confirmation UI to be skipped in testing.
230 static void SkipDirectoryConfirmationForTest();
231 static void AutoCancelDirectoryConfirmationForTest();
232 static void StopSkippingDirectoryConfirmationForTest();
233 // Call this with the directory for test file paths. On Chrome OS, accessed
234 // path needs to be explicitly registered for smooth integration with Google
235 // Drive support.
236 static void RegisterTempExternalFileSystemForTest(const std::string& name,
237 const base::FilePath& path);
238 DECLARE_EXTENSION_FUNCTION("fileSystem.chooseEntry", FILESYSTEM_CHOOSEENTRY)
240 typedef std::vector<linked_ptr<api::file_system::AcceptOption>> AcceptOptions;
242 static void BuildFileTypeInfo(
243 ui::SelectFileDialog::FileTypeInfo* file_type_info,
244 const base::FilePath::StringType& suggested_extension,
245 const AcceptOptions* accepts,
246 const bool* acceptsAllTypes);
247 static void BuildSuggestion(const std::string* opt_name,
248 base::FilePath* suggested_name,
249 base::FilePath::StringType* suggested_extension);
251 protected:
252 class FilePicker;
254 ~FileSystemChooseEntryFunction() override {}
255 bool RunAsync() override;
256 void ShowPicker(const ui::SelectFileDialog::FileTypeInfo& file_type_info,
257 ui::SelectFileDialog::Type picker_type);
259 private:
260 void SetInitialPathOnFileThread(const base::FilePath& suggested_name,
261 const base::FilePath& previous_path);
263 // FilesSelected and FileSelectionCanceled are called by the file picker.
264 void FilesSelected(const std::vector<base::FilePath>& path);
265 void FileSelectionCanceled();
267 // Check if the chosen directory is or is an ancestor of a sensitive
268 // directory. If so, show a dialog to confirm that the user wants to open the
269 // directory. Calls OnDirectoryAccessConfirmed if the directory isn't
270 // sensitive or the user chooses to open it. Otherwise, calls
271 // FileSelectionCanceled.
272 void ConfirmDirectoryAccessOnFileThread(
273 bool non_native_path,
274 const std::vector<base::FilePath>& paths,
275 content::WebContents* web_contents);
276 void OnDirectoryAccessConfirmed(const std::vector<base::FilePath>& paths);
278 base::FilePath initial_path_;
281 class FileSystemRetainEntryFunction : public ChromeAsyncExtensionFunction {
282 public:
283 DECLARE_EXTENSION_FUNCTION("fileSystem.retainEntry", FILESYSTEM_RETAINENTRY)
285 protected:
286 ~FileSystemRetainEntryFunction() override {}
287 bool RunAsync() override;
289 private:
290 // Retains the file entry referenced by |entry_id| in apps::SavedFilesService.
291 // |entry_id| must refer to an entry in an isolated file system. |path| is a
292 // path of the entry. |file_info| is base::File::Info of the entry if it can
293 // be obtained.
294 void RetainFileEntry(const std::string& entry_id,
295 const base::FilePath& path,
296 scoped_ptr<base::File::Info> file_info);
299 class FileSystemIsRestorableFunction : public ChromeSyncExtensionFunction {
300 public:
301 DECLARE_EXTENSION_FUNCTION("fileSystem.isRestorable", FILESYSTEM_ISRESTORABLE)
303 protected:
304 ~FileSystemIsRestorableFunction() override {}
305 bool RunSync() override;
308 class FileSystemRestoreEntryFunction : public FileSystemEntryFunction {
309 public:
310 DECLARE_EXTENSION_FUNCTION("fileSystem.restoreEntry", FILESYSTEM_RESTOREENTRY)
312 protected:
313 ~FileSystemRestoreEntryFunction() override {}
314 bool RunAsync() override;
317 class FileSystemObserveDirectoryFunction : public ChromeSyncExtensionFunction {
318 public:
319 DECLARE_EXTENSION_FUNCTION("fileSystem.observeDirectory",
320 FILESYSTEM_OBSERVEDIRECTORY)
322 protected:
323 ~FileSystemObserveDirectoryFunction() override {}
324 bool RunSync() override;
327 class FileSystemUnobserveEntryFunction : public ChromeSyncExtensionFunction {
328 public:
329 DECLARE_EXTENSION_FUNCTION("fileSystem.unobserveEntry",
330 FILESYSTEM_UNOBSERVEENTRY)
332 protected:
333 ~FileSystemUnobserveEntryFunction() override {}
334 bool RunSync() override;
337 class FileSystemGetObservedEntriesFunction
338 : public ChromeSyncExtensionFunction {
339 public:
340 DECLARE_EXTENSION_FUNCTION("fileSystem.getObservedEntries",
341 FILESYSTEM_GETOBSERVEDENTRIES);
343 protected:
344 ~FileSystemGetObservedEntriesFunction() override {}
345 bool RunSync() override;
348 #if !defined(OS_CHROMEOS)
349 // Stub for non Chrome OS operating systems.
350 class FileSystemRequestFileSystemFunction : public UIThreadExtensionFunction {
351 public:
352 DECLARE_EXTENSION_FUNCTION("fileSystem.requestFileSystem",
353 FILESYSTEM_REQUESTFILESYSTEM);
355 protected:
356 ~FileSystemRequestFileSystemFunction() override {}
358 // UIThreadExtensionFunction overrides.
359 ExtensionFunction::ResponseAction Run() override;
362 // Stub for non Chrome OS operating systems.
363 class FileSystemGetVolumeListFunction : public UIThreadExtensionFunction {
364 public:
365 DECLARE_EXTENSION_FUNCTION("fileSystem.getVolumeList",
366 FILESYSTEM_GETVOLUMELIST);
368 protected:
369 ~FileSystemGetVolumeListFunction() override {}
371 // UIThreadExtensionFunction overrides.
372 ExtensionFunction::ResponseAction Run() override;
375 #else
376 // Requests a file system for the specified volume id.
377 class FileSystemRequestFileSystemFunction : public UIThreadExtensionFunction {
378 public:
379 DECLARE_EXTENSION_FUNCTION("fileSystem.requestFileSystem",
380 FILESYSTEM_REQUESTFILESYSTEM)
381 FileSystemRequestFileSystemFunction();
383 protected:
384 ~FileSystemRequestFileSystemFunction() override;
386 // UIThreadExtensionFunction overrides.
387 ExtensionFunction::ResponseAction Run() override;
389 private:
390 // Called when a user grants or rejects permissions for the file system
391 // access.
392 void OnConsentReceived(const base::WeakPtr<file_manager::Volume>& volume,
393 bool writable,
394 file_system_api::ConsentProvider::Consent result);
396 ChromeExtensionFunctionDetails chrome_details_;
399 // Requests a list of available volumes.
400 class FileSystemGetVolumeListFunction : public UIThreadExtensionFunction {
401 public:
402 DECLARE_EXTENSION_FUNCTION("fileSystem.getVolumeList",
403 FILESYSTEM_GETVOLUMELIST);
404 FileSystemGetVolumeListFunction();
406 protected:
407 ~FileSystemGetVolumeListFunction() override;
409 // UIThreadExtensionFunction overrides.
410 ExtensionFunction::ResponseAction Run() override;
412 private:
413 ChromeExtensionFunctionDetails chrome_details_;
415 #endif
417 } // namespace extensions
419 #endif // CHROME_BROWSER_EXTENSIONS_API_FILE_SYSTEM_FILE_SYSTEM_API_H_