ExtensionSyncService: listen for relevant changes instead of being explicitly called...
[chromium-blink-merge.git] / chrome / browser / file_select_helper.h
blob0067b8a11c5c4b804068fa930a83f4ce4089c568
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_FILE_SELECT_HELPER_H_
6 #define CHROME_BROWSER_FILE_SELECT_HELPER_H_
8 #include <map>
9 #include <vector>
11 #include "base/compiler_specific.h"
12 #include "base/gtest_prod_util.h"
13 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_registrar.h"
15 #include "content/public/browser/web_contents_observer.h"
16 #include "content/public/common/file_chooser_params.h"
17 #include "net/base/directory_lister.h"
18 #include "ui/shell_dialogs/select_file_dialog.h"
20 class Profile;
22 namespace content {
23 struct FileChooserFileInfo;
24 class RenderViewHost;
25 class WebContents;
28 namespace ui {
29 struct SelectedFileInfo;
32 // This class handles file-selection requests coming from WebUI elements
33 // (via the extensions::ExtensionHost class). It implements both the
34 // initialisation and listener functions for file-selection dialogs.
35 class FileSelectHelper : public base::RefCountedThreadSafe<FileSelectHelper>,
36 public ui::SelectFileDialog::Listener,
37 public content::WebContentsObserver,
38 public content::NotificationObserver {
39 public:
41 // Show the file chooser dialog.
42 static void RunFileChooser(content::WebContents* tab,
43 const content::FileChooserParams& params);
45 // Enumerates all the files in directory.
46 static void EnumerateDirectory(content::WebContents* tab,
47 int request_id,
48 const base::FilePath& path);
50 private:
51 friend class base::RefCountedThreadSafe<FileSelectHelper>;
52 FRIEND_TEST_ALL_PREFIXES(FileSelectHelperTest, IsAcceptTypeValid);
53 FRIEND_TEST_ALL_PREFIXES(FileSelectHelperTest, ZipPackage);
54 explicit FileSelectHelper(Profile* profile);
55 ~FileSelectHelper() override;
57 // Utility class which can listen for directory lister events and relay
58 // them to the main object with the correct tracking id.
59 class DirectoryListerDispatchDelegate
60 : public net::DirectoryLister::DirectoryListerDelegate {
61 public:
62 DirectoryListerDispatchDelegate(FileSelectHelper* parent, int id)
63 : parent_(parent),
64 id_(id) {}
65 ~DirectoryListerDispatchDelegate() override {}
66 void OnListFile(
67 const net::DirectoryLister::DirectoryListerData& data) override;
68 void OnListDone(int error) override;
70 private:
71 // This FileSelectHelper owns this object.
72 FileSelectHelper* parent_;
73 int id_;
75 DISALLOW_COPY_AND_ASSIGN(DirectoryListerDispatchDelegate);
78 void RunFileChooser(content::RenderViewHost* render_view_host,
79 content::WebContents* web_contents,
80 const content::FileChooserParams& params);
81 void RunFileChooserOnFileThread(
82 const content::FileChooserParams& params);
83 void RunFileChooserOnUIThread(
84 const content::FileChooserParams& params);
86 // Cleans up and releases this instance. This must be called after the last
87 // callback is received from the file chooser dialog.
88 void RunFileChooserEnd();
90 // SelectFileDialog::Listener overrides.
91 void FileSelected(const base::FilePath& path,
92 int index,
93 void* params) override;
94 void FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file,
95 int index,
96 void* params) override;
97 void MultiFilesSelected(const std::vector<base::FilePath>& files,
98 void* params) override;
99 void MultiFilesSelectedWithExtraInfo(
100 const std::vector<ui::SelectedFileInfo>& files,
101 void* params) override;
102 void FileSelectionCanceled(void* params) override;
104 // content::NotificationObserver overrides.
105 void Observe(int type,
106 const content::NotificationSource& source,
107 const content::NotificationDetails& details) override;
109 // content::WebContentsObserver overrides.
110 void RenderViewHostChanged(content::RenderViewHost* old_host,
111 content::RenderViewHost* new_host) override;
112 void WebContentsDestroyed() override;
114 void EnumerateDirectory(int request_id,
115 content::RenderViewHost* render_view_host,
116 const base::FilePath& path);
118 // Kicks off a new directory enumeration.
119 void StartNewEnumeration(const base::FilePath& path,
120 int request_id,
121 content::RenderViewHost* render_view_host);
123 // Callbacks from directory enumeration.
124 virtual void OnListFile(
125 int id,
126 const net::DirectoryLister::DirectoryListerData& data);
127 virtual void OnListDone(int id, int error);
129 // Cleans up and releases this instance. This must be called after the last
130 // callback is received from the enumeration code.
131 void EnumerateDirectoryEnd();
133 #if defined(OS_MACOSX) && !defined(OS_IOS)
134 // Must be called on the FILE_USER_BLOCKING thread. Each selected file that is
135 // a package will be zipped, and the zip will be passed to the render view
136 // host in place of the package.
137 void ProcessSelectedFilesMac(const std::vector<ui::SelectedFileInfo>& files);
139 // Saves the paths of |zipped_files| for later deletion. Passes |files| to the
140 // render view host.
141 void ProcessSelectedFilesMacOnUIThread(
142 const std::vector<ui::SelectedFileInfo>& files,
143 const std::vector<base::FilePath>& zipped_files);
145 // Zips the package at |path| into a temporary destination. Returns the
146 // temporary destination, if the zip was successful. Otherwise returns an
147 // empty path.
148 static base::FilePath ZipPackage(const base::FilePath& path);
149 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
151 // Utility method that passes |files| to the render view host, and ends the
152 // file chooser.
153 void NotifyRenderViewHostAndEnd(
154 const std::vector<ui::SelectedFileInfo>& files);
156 // Sends the result to the render process, and call |RunFileChooserEnd|.
157 void NotifyRenderViewHostAndEndAfterConversion(
158 const std::vector<content::FileChooserFileInfo>& list);
160 // Schedules the deletion of the files in |temporary_files_| and clears the
161 // vector.
162 void DeleteTemporaryFiles();
164 // Cleans up when the RenderViewHost of our WebContents changes.
165 void CleanUpOnRenderViewHostChange();
167 // Helper method to get allowed extensions for select file dialog from
168 // the specified accept types as defined in the spec:
169 // http://whatwg.org/html/number-state.html#attr-input-accept
170 // |accept_types| contains only valid lowercased MIME types or file extensions
171 // beginning with a period (.).
172 static scoped_ptr<ui::SelectFileDialog::FileTypeInfo>
173 GetFileTypesFromAcceptType(
174 const std::vector<base::string16>& accept_types);
176 // Check the accept type is valid. It is expected to be all lower case with
177 // no whitespace.
178 static bool IsAcceptTypeValid(const std::string& accept_type);
180 // Profile used to set/retrieve the last used directory.
181 Profile* profile_;
183 // The RenderViewHost and WebContents for the page showing a file dialog
184 // (may only be one such dialog).
185 content::RenderViewHost* render_view_host_;
186 content::WebContents* web_contents_;
188 // Dialog box used for choosing files to upload from file form fields.
189 scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
190 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> select_file_types_;
192 // The type of file dialog last shown.
193 ui::SelectFileDialog::Type dialog_type_;
195 // The mode of file dialog last shown.
196 content::FileChooserParams::Mode dialog_mode_;
198 // Maintain a list of active directory enumerations. These could come from
199 // the file select dialog or from drag-and-drop of directories, so there could
200 // be more than one going on at a time.
201 struct ActiveDirectoryEnumeration;
202 std::map<int, ActiveDirectoryEnumeration*> directory_enumerations_;
204 // Registrar for notifications regarding our RenderViewHost.
205 content::NotificationRegistrar notification_registrar_;
207 // Temporary files only used on OSX. This class is responsible for deleting
208 // these files when they are no longer needed.
209 std::vector<base::FilePath> temporary_files_;
211 DISALLOW_COPY_AND_ASSIGN(FileSelectHelper);
214 #endif // CHROME_BROWSER_FILE_SELECT_HELPER_H_