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 XWALK_RUNTIME_BROWSER_RUNTIME_FILE_SELECT_HELPER_H_
6 #define XWALK_RUNTIME_BROWSER_RUNTIME_FILE_SELECT_HELPER_H_
12 #include "base/compiler_specific.h"
13 #include "base/gtest_prod_util.h"
14 #include "content/public/browser/notification_observer.h"
15 #include "content/public/browser/notification_registrar.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"
26 struct SelectedFileInfo;
29 // This class handles file-selection requests coming from WebUI elements
30 // (via the extensions::ExtensionHost class). It implements both the
31 // initialisation and listener functions for file-selection dialogs.
32 class RuntimeFileSelectHelper
33 : public base::RefCountedThreadSafe<RuntimeFileSelectHelper>,
34 public ui::SelectFileDialog::Listener,
35 public content::NotificationObserver {
37 // Show the file chooser dialog.
38 static void RunFileChooser(content::WebContents* tab,
39 const content::FileChooserParams& params);
41 // Enumerates all the files in directory.
42 static void EnumerateDirectory(content::WebContents* tab,
44 const base::FilePath& path);
47 friend class base::RefCountedThreadSafe<RuntimeFileSelectHelper>;
48 FRIEND_TEST_ALL_PREFIXES(RuntimeFileSelectHelperTest, IsAcceptTypeValid);
49 explicit RuntimeFileSelectHelper();
50 virtual ~RuntimeFileSelectHelper();
52 // Utility class which can listen for directory lister events and relay
53 // them to the main object with the correct tracking id.
54 class DirectoryListerDispatchDelegate
55 : public net::DirectoryLister::DirectoryListerDelegate {
57 DirectoryListerDispatchDelegate(RuntimeFileSelectHelper* parent, int id)
60 virtual ~DirectoryListerDispatchDelegate() {}
61 virtual void OnListFile(
62 const net::DirectoryLister::DirectoryListerData& data) OVERRIDE;
63 virtual void OnListDone(int error) OVERRIDE;
65 // This RuntimeFileSelectHelper owns this object.
66 RuntimeFileSelectHelper* parent_;
69 DISALLOW_COPY_AND_ASSIGN(DirectoryListerDispatchDelegate);
72 void RunFileChooser(content::RenderViewHost* render_view_host,
73 content::WebContents* web_contents,
74 const content::FileChooserParams& params);
75 void RunFileChooserOnFileThread(
76 const content::FileChooserParams& params);
77 void RunFileChooserOnUIThread(
78 const content::FileChooserParams& params);
80 // Cleans up and releases this instance. This must be called after the last
81 // callback is received from the file chooser dialog.
82 void RunFileChooserEnd();
84 // SelectFileDialog::Listener overrides.
85 virtual void FileSelected(
86 const base::FilePath& path, int index, void* params) OVERRIDE;
87 virtual void FileSelectedWithExtraInfo(
88 const ui::SelectedFileInfo& file,
90 void* params) OVERRIDE;
91 virtual void MultiFilesSelected(const std::vector<base::FilePath>& files,
92 void* params) OVERRIDE;
93 virtual void MultiFilesSelectedWithExtraInfo(
94 const std::vector<ui::SelectedFileInfo>& files,
95 void* params) OVERRIDE;
96 virtual void FileSelectionCanceled(void* params) OVERRIDE;
98 // content::NotificationObserver overrides.
99 virtual void Observe(int type,
100 const content::NotificationSource& source,
101 const content::NotificationDetails& details) OVERRIDE;
103 void EnumerateDirectory(int request_id,
104 content::RenderViewHost* render_view_host,
105 const base::FilePath& path);
107 // Kicks off a new directory enumeration.
108 void StartNewEnumeration(const base::FilePath& path,
110 content::RenderViewHost* render_view_host);
112 // Callbacks from directory enumeration.
113 virtual void OnListFile(
115 const net::DirectoryLister::DirectoryListerData& data);
116 virtual void OnListDone(int id, int error);
118 // Cleans up and releases this instance. This must be called after the last
119 // callback is received from the enumeration code.
120 void EnumerateDirectoryEnd();
122 // Helper method to get allowed extensions for select file dialog from
123 // the specified accept types as defined in the spec:
124 // http://whatwg.org/html/number-state.html#attr-input-accept
125 // |accept_types| contains only valid lowercased MIME types or file extensions
126 // beginning with a period (.).
127 static scoped_ptr<ui::SelectFileDialog::FileTypeInfo>
128 GetFileTypesFromAcceptType(const std::vector<base::string16>& accept_types);
130 // Check the accept type is valid. It is expected to be all lower case with
132 static bool IsAcceptTypeValid(const std::string& accept_type);
134 // The RenderViewHost and WebContents for the page showing a file dialog
135 // (may only be one such dialog).
136 content::RenderViewHost* render_view_host_;
137 content::WebContents* web_contents_;
139 // Dialog box used for choosing files to upload from file form fields.
140 scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
141 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> select_file_types_;
143 // The type of file dialog last shown.
144 ui::SelectFileDialog::Type dialog_type_;
146 content::FileChooserParams::Mode dialog_mode_;
148 // Maintain a list of active directory enumerations. These could come from
149 // the file select dialog or from drag-and-drop of directories, so there could
150 // be more than one going on at a time.
151 struct ActiveDirectoryEnumeration;
152 std::map<int, ActiveDirectoryEnumeration*> directory_enumerations_;
154 // Registrar for notifications regarding our RenderViewHost.
155 content::NotificationRegistrar notification_registrar_;
157 DISALLOW_COPY_AND_ASSIGN(RuntimeFileSelectHelper);
160 #endif // XWALK_RUNTIME_BROWSER_RUNTIME_FILE_SELECT_HELPER_H_