b94e53d8ba0e014ef652066b240f41494c206dd1
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / runtime_file_select_helper.h
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.
4
5 #ifndef XWALK_RUNTIME_BROWSER_RUNTIME_FILE_SELECT_HELPER_H_
6 #define XWALK_RUNTIME_BROWSER_RUNTIME_FILE_SELECT_HELPER_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
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"
19
20 namespace content {
21 class RenderViewHost;
22 class WebContents;
23 }
24
25 namespace ui {
26 struct SelectedFileInfo;
27 }
28
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 {
36  public:
37   // Show the file chooser dialog.
38   static void RunFileChooser(content::WebContents* tab,
39                              const content::FileChooserParams& params);
40
41   // Enumerates all the files in directory.
42   static void EnumerateDirectory(content::WebContents* tab,
43                                  int request_id,
44                                  const base::FilePath& path);
45
46  private:
47   friend class base::RefCountedThreadSafe<RuntimeFileSelectHelper>;
48   FRIEND_TEST_ALL_PREFIXES(RuntimeFileSelectHelperTest, IsAcceptTypeValid);
49   explicit RuntimeFileSelectHelper();
50   virtual ~RuntimeFileSelectHelper();
51
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 {
56    public:
57     DirectoryListerDispatchDelegate(RuntimeFileSelectHelper* parent, int id)
58         : parent_(parent),
59           id_(id) {}
60     virtual ~DirectoryListerDispatchDelegate() {}
61     virtual void OnListFile(
62         const net::DirectoryLister::DirectoryListerData& data) OVERRIDE;
63     virtual void OnListDone(int error) OVERRIDE;
64    private:
65     // This RuntimeFileSelectHelper owns this object.
66     RuntimeFileSelectHelper* parent_;
67     int id_;
68
69     DISALLOW_COPY_AND_ASSIGN(DirectoryListerDispatchDelegate);
70   };
71
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);
79
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();
83
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,
89       int index,
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;
97
98   // content::NotificationObserver overrides.
99   virtual void Observe(int type,
100                        const content::NotificationSource& source,
101                        const content::NotificationDetails& details) OVERRIDE;
102
103   void EnumerateDirectory(int request_id,
104                           content::RenderViewHost* render_view_host,
105                           const base::FilePath& path);
106
107   // Kicks off a new directory enumeration.
108   void StartNewEnumeration(const base::FilePath& path,
109                            int request_id,
110                            content::RenderViewHost* render_view_host);
111
112   // Callbacks from directory enumeration.
113   virtual void OnListFile(
114       int id,
115       const net::DirectoryLister::DirectoryListerData& data);
116   virtual void OnListDone(int id, int error);
117
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();
121
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);
129
130   // Check the accept type is valid. It is expected to be all lower case with
131   // no whitespace.
132   static bool IsAcceptTypeValid(const std::string& accept_type);
133
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_;
138
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_;
142
143   // The type of file dialog last shown.
144   ui::SelectFileDialog::Type dialog_type_;
145
146   content::FileChooserParams::Mode dialog_mode_;
147
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_;
153
154   // Registrar for notifications regarding our RenderViewHost.
155   content::NotificationRegistrar notification_registrar_;
156
157   DISALLOW_COPY_AND_ASSIGN(RuntimeFileSelectHelper);
158 };
159
160 #endif  // XWALK_RUNTIME_BROWSER_RUNTIME_FILE_SELECT_HELPER_H_