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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/file_select_helper.cc
===================================================================
--- chrome/browser/file_select_helper.cc (revision 79702)
+++ chrome/browser/file_select_helper.cc (working copy)
@@ -12,6 +12,8 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
+#include "content/browser/child_process_security_policy.h"
+#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/tab_contents.h"
@@ -22,6 +24,14 @@
#include "net/base/mime_util.h"
#include "ui/base/l10n/l10n_util.h"
+namespace {
+
+// There is only one file-selection happening at any given time,
+// so we allocate an enumeration ID for that purpose. All IDs from
+// the renderer must start at 0 and increase.
+static const int kFileSelectEnumerationId = -1;
+}
+
FileSelectHelper::FileSelectHelper(Profile* profile)
: profile_(profile),
render_view_host_(NULL),
@@ -35,10 +45,17 @@
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
- // Stop any pending directory enumeration and prevent a callback.
- if (directory_lister_.get()) {
- directory_lister_->set_delegate(NULL);
- directory_lister_->Cancel();
+ // Stop any pending directory enumeration, prevent a callback, and free
+ // allocated memory.
+ std::map<int, ActiveDirectoryEnumeration*>::iterator iter;
+ for (iter = directory_enumerations_.begin();
+ iter != directory_enumerations_.end();
+ ++iter) {
+ if (iter->second->lister_.get()) {
+ iter->second->lister_->set_delegate(NULL);
+ iter->second->lister_->Cancel();
+ }
+ delete iter->second;
}
}
@@ -50,7 +67,7 @@
profile_->set_last_selected_directory(path.DirName());
if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) {
- DirectorySelected(path);
+ StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_);
return;
}
@@ -85,40 +102,55 @@
render_view_host_ = NULL;
}
-void FileSelectHelper::DirectorySelected(const FilePath& path) {
- directory_lister_ = new net::DirectoryLister(path,
- true,
- net::DirectoryLister::NO_SORT,
- this);
- if (!directory_lister_->Start())
- FileSelectionCanceled(NULL);
+void FileSelectHelper::StartNewEnumeration(const FilePath& path,
+ int request_id,
+ RenderViewHost* render_view_host) {
+ scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration);
+ entry->rvh_ = render_view_host;
+ entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id));
+ entry->lister_ = new net::DirectoryLister(path,
+ true,
+ net::DirectoryLister::NO_SORT,
+ entry->delegate_.get());
+ if (!entry->lister_->Start()) {
+ if (request_id == kFileSelectEnumerationId)
+ FileSelectionCanceled(NULL);
+ else
+ render_view_host->DirectoryEnumerationFinished(request_id,
+ entry->results_);
+ } else {
+ directory_enumerations_[request_id] = entry.release();
+ }
}
void FileSelectHelper::OnListFile(
+ int id,
const net::DirectoryLister::DirectoryListerData& data) {
+ ActiveDirectoryEnumeration* entry = directory_enumerations_[id];
+
// Directory upload returns directories via a "." file, so that
// empty directories are included. This util call just checks
// the flags in the structure; there's no file I/O going on.
if (file_util::FileEnumerator::IsDirectory(data.info))
- directory_lister_results_.push_back(
- data.path.Append(FILE_PATH_LITERAL(".")));
+ entry->results_.push_back(data.path.Append(FILE_PATH_LITERAL(".")));
else
- directory_lister_results_.push_back(data.path);
+ entry->results_.push_back(data.path);
}
-void FileSelectHelper::OnListDone(int error) {
- if (!render_view_host_)
+void FileSelectHelper::OnListDone(int id, int error) {
+ // This entry needs to be cleaned up when this function is done.
+ scoped_ptr<ActiveDirectoryEnumeration> entry(directory_enumerations_[id]);
+ directory_enumerations_.erase(id);
+ if (!entry->rvh_)
return;
-
if (error) {
FileSelectionCanceled(NULL);
return;
}
-
- render_view_host_->FilesSelectedInChooser(directory_lister_results_);
- render_view_host_ = NULL;
- directory_lister_ = NULL;
- directory_lister_results_.clear();
+ if (id == kFileSelectEnumerationId)
+ entry->rvh_->FilesSelectedInChooser(entry->results_);
+ else
+ entry->rvh_->DirectoryEnumerationFinished(id, entry->results_);
}
SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType(
@@ -239,6 +271,13 @@
NULL);
}
+void FileSelectHelper::EnumerateDirectory(int request_id,
+ RenderViewHost* render_view_host,
+ const FilePath& path) {
+ DCHECK_NE(kFileSelectEnumerationId, request_id);
+ StartNewEnumeration(path, request_id, render_view_host);
+}
+
void FileSelectHelper::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -258,6 +297,7 @@
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(FileSelectObserver, message)
IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_EnumerateDirectory, OnEnumerateDirectory)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -271,3 +311,20 @@
file_select_helper_->RunFileChooser(tab_contents()->render_view_host(),
params);
}
+
+void FileSelectObserver::OnEnumerateDirectory(int request_id,
+ const FilePath& path) {
+ ChildProcessSecurityPolicy* policy =
+ ChildProcessSecurityPolicy::GetInstance();
+ if (!policy->CanReadDirectory(
+ tab_contents()->render_view_host()->process()->id(),
+ path)) {
+ return;
+ }
+
+ if (!file_select_helper_.get())
+ file_select_helper_.reset(new FileSelectHelper(tab_contents()->profile()));
+ file_select_helper_->EnumerateDirectory(request_id,
+ tab_contents()->render_view_host(),
+ path);
+}
« 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