Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: chrome/browser/file_select_helper.cc

Issue 6623015: Add a path for a web page to request the enumeration of a directory. This, t... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/file_select_helper.h ('k') | content/browser/child_process_security_policy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/file_select_helper.h" 5 #include "chrome/browser/file_select_helper.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/string_split.h" 10 #include "base/string_split.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/platform_util.h" 13 #include "chrome/browser/platform_util.h"
14 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
15 #include "content/browser/child_process_security_policy.h"
16 #include "content/browser/renderer_host/render_process_host.h"
15 #include "content/browser/renderer_host/render_view_host.h" 17 #include "content/browser/renderer_host/render_view_host.h"
16 #include "content/browser/renderer_host/render_widget_host_view.h" 18 #include "content/browser/renderer_host/render_widget_host_view.h"
17 #include "content/browser/tab_contents/tab_contents.h" 19 #include "content/browser/tab_contents/tab_contents.h"
18 #include "content/common/notification_details.h" 20 #include "content/common/notification_details.h"
19 #include "content/common/notification_source.h" 21 #include "content/common/notification_source.h"
20 #include "content/common/view_messages.h" 22 #include "content/common/view_messages.h"
21 #include "grit/generated_resources.h" 23 #include "grit/generated_resources.h"
22 #include "net/base/mime_util.h" 24 #include "net/base/mime_util.h"
23 #include "ui/base/l10n/l10n_util.h" 25 #include "ui/base/l10n/l10n_util.h"
24 26
27 namespace {
28
29 // There is only one file-selection happening at any given time,
30 // so we allocate an enumeration ID for that purpose. All IDs from
31 // the renderer must start at 0 and increase.
32 static const int kFileSelectEnumerationId = -1;
33 }
34
25 FileSelectHelper::FileSelectHelper(Profile* profile) 35 FileSelectHelper::FileSelectHelper(Profile* profile)
26 : profile_(profile), 36 : profile_(profile),
27 render_view_host_(NULL), 37 render_view_host_(NULL),
28 select_file_dialog_(), 38 select_file_dialog_(),
29 dialog_type_(SelectFileDialog::SELECT_OPEN_FILE) { 39 dialog_type_(SelectFileDialog::SELECT_OPEN_FILE) {
30 } 40 }
31 41
32 FileSelectHelper::~FileSelectHelper() { 42 FileSelectHelper::~FileSelectHelper() {
33 // There may be pending file dialogs, we need to tell them that we've gone 43 // There may be pending file dialogs, we need to tell them that we've gone
34 // away so they don't try and call back to us. 44 // away so they don't try and call back to us.
35 if (select_file_dialog_.get()) 45 if (select_file_dialog_.get())
36 select_file_dialog_->ListenerDestroyed(); 46 select_file_dialog_->ListenerDestroyed();
37 47
38 // Stop any pending directory enumeration and prevent a callback. 48 // Stop any pending directory enumeration, prevent a callback, and free
39 if (directory_lister_.get()) { 49 // allocated memory.
40 directory_lister_->set_delegate(NULL); 50 std::map<int, ActiveDirectoryEnumeration*>::iterator iter;
41 directory_lister_->Cancel(); 51 for (iter = directory_enumerations_.begin();
52 iter != directory_enumerations_.end();
53 ++iter) {
54 if (iter->second->lister_.get()) {
55 iter->second->lister_->set_delegate(NULL);
56 iter->second->lister_->Cancel();
57 }
58 delete iter->second;
42 } 59 }
43 } 60 }
44 61
45 void FileSelectHelper::FileSelected(const FilePath& path, 62 void FileSelectHelper::FileSelected(const FilePath& path,
46 int index, void* params) { 63 int index, void* params) {
47 if (!render_view_host_) 64 if (!render_view_host_)
48 return; 65 return;
49 66
50 profile_->set_last_selected_directory(path.DirName()); 67 profile_->set_last_selected_directory(path.DirName());
51 68
52 if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) { 69 if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) {
53 DirectorySelected(path); 70 StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_);
54 return; 71 return;
55 } 72 }
56 73
57 std::vector<FilePath> files; 74 std::vector<FilePath> files;
58 files.push_back(path); 75 files.push_back(path);
59 render_view_host_->FilesSelectedInChooser(files); 76 render_view_host_->FilesSelectedInChooser(files);
60 // We are done with this showing of the dialog. 77 // We are done with this showing of the dialog.
61 render_view_host_ = NULL; 78 render_view_host_ = NULL;
62 } 79 }
63 80
(...skipping 14 matching lines...) Expand all
78 return; 95 return;
79 96
80 // If the user cancels choosing a file to upload we pass back an 97 // If the user cancels choosing a file to upload we pass back an
81 // empty vector. 98 // empty vector.
82 render_view_host_->FilesSelectedInChooser(std::vector<FilePath>()); 99 render_view_host_->FilesSelectedInChooser(std::vector<FilePath>());
83 100
84 // We are done with this showing of the dialog. 101 // We are done with this showing of the dialog.
85 render_view_host_ = NULL; 102 render_view_host_ = NULL;
86 } 103 }
87 104
88 void FileSelectHelper::DirectorySelected(const FilePath& path) { 105 void FileSelectHelper::StartNewEnumeration(const FilePath& path,
89 directory_lister_ = new net::DirectoryLister(path, 106 int request_id,
90 true, 107 RenderViewHost* render_view_host) {
91 net::DirectoryLister::NO_SORT, 108 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration);
92 this); 109 entry->rvh_ = render_view_host;
93 if (!directory_lister_->Start()) 110 entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id));
94 FileSelectionCanceled(NULL); 111 entry->lister_ = new net::DirectoryLister(path,
112 true,
113 net::DirectoryLister::NO_SORT,
114 entry->delegate_.get());
115 if (!entry->lister_->Start()) {
116 if (request_id == kFileSelectEnumerationId)
117 FileSelectionCanceled(NULL);
118 else
119 render_view_host->DirectoryEnumerationFinished(request_id,
120 entry->results_);
121 } else {
122 directory_enumerations_[request_id] = entry.release();
123 }
95 } 124 }
96 125
97 void FileSelectHelper::OnListFile( 126 void FileSelectHelper::OnListFile(
127 int id,
98 const net::DirectoryLister::DirectoryListerData& data) { 128 const net::DirectoryLister::DirectoryListerData& data) {
129 ActiveDirectoryEnumeration* entry = directory_enumerations_[id];
130
99 // Directory upload returns directories via a "." file, so that 131 // Directory upload returns directories via a "." file, so that
100 // empty directories are included. This util call just checks 132 // empty directories are included. This util call just checks
101 // the flags in the structure; there's no file I/O going on. 133 // the flags in the structure; there's no file I/O going on.
102 if (file_util::FileEnumerator::IsDirectory(data.info)) 134 if (file_util::FileEnumerator::IsDirectory(data.info))
103 directory_lister_results_.push_back( 135 entry->results_.push_back(data.path.Append(FILE_PATH_LITERAL(".")));
104 data.path.Append(FILE_PATH_LITERAL(".")));
105 else 136 else
106 directory_lister_results_.push_back(data.path); 137 entry->results_.push_back(data.path);
107 } 138 }
108 139
109 void FileSelectHelper::OnListDone(int error) { 140 void FileSelectHelper::OnListDone(int id, int error) {
110 if (!render_view_host_) 141 // This entry needs to be cleaned up when this function is done.
142 scoped_ptr<ActiveDirectoryEnumeration> entry(directory_enumerations_[id]);
143 directory_enumerations_.erase(id);
144 if (!entry->rvh_)
111 return; 145 return;
112
113 if (error) { 146 if (error) {
114 FileSelectionCanceled(NULL); 147 FileSelectionCanceled(NULL);
115 return; 148 return;
116 } 149 }
117 150 if (id == kFileSelectEnumerationId)
118 render_view_host_->FilesSelectedInChooser(directory_lister_results_); 151 entry->rvh_->FilesSelectedInChooser(entry->results_);
119 render_view_host_ = NULL; 152 else
120 directory_lister_ = NULL; 153 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_);
121 directory_lister_results_.clear();
122 } 154 }
123 155
124 SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType( 156 SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType(
125 const string16& accept_types) { 157 const string16& accept_types) {
126 if (accept_types.empty()) 158 if (accept_types.empty())
127 return NULL; 159 return NULL;
128 160
129 // Split the accept-type string on commas. 161 // Split the accept-type string on commas.
130 std::vector<string16> mime_types; 162 std::vector<string16> mime_types;
131 base::SplitStringUsingSubstr(accept_types, ASCIIToUTF16(","), &mime_types); 163 base::SplitStringUsingSubstr(accept_types, ASCIIToUTF16(","), &mime_types);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 select_file_dialog_->SelectFile(dialog_type_, 264 select_file_dialog_->SelectFile(dialog_type_,
233 params.title, 265 params.title,
234 default_file_name, 266 default_file_name,
235 file_types.get(), 267 file_types.get(),
236 file_types.get() ? 1 : 0, // 1-based index. 268 file_types.get() ? 1 : 0, // 1-based index.
237 FILE_PATH_LITERAL(""), 269 FILE_PATH_LITERAL(""),
238 owning_window, 270 owning_window,
239 NULL); 271 NULL);
240 } 272 }
241 273
274 void FileSelectHelper::EnumerateDirectory(int request_id,
275 RenderViewHost* render_view_host,
276 const FilePath& path) {
277 DCHECK_NE(kFileSelectEnumerationId, request_id);
278 StartNewEnumeration(path, request_id, render_view_host);
279 }
280
242 void FileSelectHelper::Observe(NotificationType type, 281 void FileSelectHelper::Observe(NotificationType type,
243 const NotificationSource& source, 282 const NotificationSource& source,
244 const NotificationDetails& details) { 283 const NotificationDetails& details) {
245 DCHECK(type == NotificationType::RENDER_WIDGET_HOST_DESTROYED); 284 DCHECK(type == NotificationType::RENDER_WIDGET_HOST_DESTROYED);
246 DCHECK(Details<RenderViewHost>(details).ptr() == render_view_host_); 285 DCHECK(Details<RenderViewHost>(details).ptr() == render_view_host_);
247 render_view_host_ = NULL; 286 render_view_host_ = NULL;
248 } 287 }
249 288
250 FileSelectObserver::FileSelectObserver(TabContents* tab_contents) 289 FileSelectObserver::FileSelectObserver(TabContents* tab_contents)
251 : TabContentsObserver(tab_contents) { 290 : TabContentsObserver(tab_contents) {
252 } 291 }
253 292
254 FileSelectObserver::~FileSelectObserver() { 293 FileSelectObserver::~FileSelectObserver() {
255 } 294 }
256 295
257 bool FileSelectObserver::OnMessageReceived(const IPC::Message& message) { 296 bool FileSelectObserver::OnMessageReceived(const IPC::Message& message) {
258 bool handled = true; 297 bool handled = true;
259 IPC_BEGIN_MESSAGE_MAP(FileSelectObserver, message) 298 IPC_BEGIN_MESSAGE_MAP(FileSelectObserver, message)
260 IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser) 299 IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
300 IPC_MESSAGE_HANDLER(ViewHostMsg_EnumerateDirectory, OnEnumerateDirectory)
261 IPC_MESSAGE_UNHANDLED(handled = false) 301 IPC_MESSAGE_UNHANDLED(handled = false)
262 IPC_END_MESSAGE_MAP() 302 IPC_END_MESSAGE_MAP()
263 303
264 return handled; 304 return handled;
265 } 305 }
266 306
267 void FileSelectObserver::OnRunFileChooser( 307 void FileSelectObserver::OnRunFileChooser(
268 const ViewHostMsg_RunFileChooser_Params& params) { 308 const ViewHostMsg_RunFileChooser_Params& params) {
269 if (!file_select_helper_.get()) 309 if (!file_select_helper_.get())
270 file_select_helper_.reset(new FileSelectHelper(tab_contents()->profile())); 310 file_select_helper_.reset(new FileSelectHelper(tab_contents()->profile()));
271 file_select_helper_->RunFileChooser(tab_contents()->render_view_host(), 311 file_select_helper_->RunFileChooser(tab_contents()->render_view_host(),
272 params); 312 params);
273 } 313 }
314
315 void FileSelectObserver::OnEnumerateDirectory(int request_id,
316 const FilePath& path) {
317 ChildProcessSecurityPolicy* policy =
318 ChildProcessSecurityPolicy::GetInstance();
319 if (!policy->CanReadDirectory(
320 tab_contents()->render_view_host()->process()->id(),
321 path)) {
322 return;
323 }
324
325 if (!file_select_helper_.get())
326 file_select_helper_.reset(new FileSelectHelper(tab_contents()->profile()));
327 file_select_helper_->EnumerateDirectory(request_id,
328 tab_contents()->render_view_host(),
329 path);
330 }
OLDNEW
« no previous file with comments | « chrome/browser/file_select_helper.h ('k') | content/browser/child_process_security_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698