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

Unified Diff: content/renderer/render_frame_impl.cc

Issue 2050623005: Move file chooser from RenderView(Host) to RenderFrame(Host). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Some cleanup. Created 4 years, 6 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
Index: content/renderer/render_frame_impl.cc
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 13392d1784ee20bce387f8fdb3496debf9589912..8d285ccff6154a90b01f12d287e2f1d7e3a8578e 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -69,6 +69,8 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
+#include "content/public/common/file_chooser_file_info.h"
+#include "content/public/common/file_chooser_params.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/common/page_state.h"
#include "content/public/common/resource_response.h"
@@ -151,6 +153,7 @@
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/http/http_util.h"
#include "storage/common/data_element.h"
+#include "third_party/WebKit/public/platform/FilePathConversion.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebCachePolicy.h"
#include "third_party/WebKit/public/platform/WebData.h"
@@ -851,6 +854,14 @@ bool UseMojoCdm() {
} // namespace
+struct RenderFrameImpl::PendingFileChooser {
+ PendingFileChooser(const FileChooserParams& p,
+ blink::WebFileChooserCompletion* c)
+ : params(p), completion(c) {}
+ FileChooserParams params;
+ blink::WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
+};
+
// static
RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view,
int32_t routing_id) {
@@ -1114,6 +1125,15 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
}
RenderFrameImpl::~RenderFrameImpl() {
+ // If file chooser is still waiting for answer, dispatch empty answer.
+ while (!file_chooser_completions_.empty()) {
+ if (file_chooser_completions_.front()->completion) {
+ file_chooser_completions_.front()->completion->didChooseFile(
+ WebVector<WebString>());
+ }
+ file_chooser_completions_.pop_front();
+ }
+
FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone());
FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct());
@@ -1505,6 +1525,7 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameMsg_EnableViewSourceMode, OnEnableViewSourceMode)
IPC_MESSAGE_HANDLER(FrameMsg_SuppressFurtherDialogs,
OnSuppressFurtherDialogs)
+ IPC_MESSAGE_HANDLER(FrameMsg_RunFileChooserResponse, OnFileChooserResponse)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(FrameMsg_ActivateNearestFindResult,
OnActivateNearestFindResult)
@@ -2218,6 +2239,31 @@ bool RenderFrameImpl::RunJavaScriptMessage(JavaScriptMessageType type,
return success;
}
+bool RenderFrameImpl::ScheduleFileChooser(
+ const FileChooserParams& params,
+ blink::WebFileChooserCompletion* completion) {
+ static const size_t kMaximumPendingFileChooseRequests = 4;
+ if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
+ // This sanity check prevents too many file choose requests from getting
+ // queued which could DoS the user. Getting these is most likely a
+ // programming error (there are many ways to DoS the user so it's not
+ // considered a "real" security check), either in JS requesting many file
+ // choosers to pop up, or in a plugin.
+ //
+ // TODO(brettw) we might possibly want to require a user gesture to open
Avi (use Gerrit) 2016/06/10 21:52:54 TODO(brettw): We ...
nasko 2016/06/10 22:07:50 Done.
+ // a file picker, which will address this issue in a better way.
+ return false;
+ }
+
+ file_chooser_completions_.push_back(
+ base::WrapUnique(new PendingFileChooser(params, completion)));
+ if (file_chooser_completions_.size() == 1) {
+ // Actually show the browse dialog when this is the first request.
+ Send(new FrameHostMsg_RunFileChooser(routing_id_, params));
+ }
+ return true;
+}
+
void RenderFrameImpl::LoadNavigationErrorPage(
const WebURLRequest& failed_request,
const WebURLError& error,
@@ -3744,6 +3790,37 @@ bool RenderFrameImpl::runModalBeforeUnloadDialog(bool is_reload) {
return success;
}
+bool RenderFrameImpl::runFileChooser(
+ const blink::WebFileChooserParams& params,
+ blink::WebFileChooserCompletion* chooser_completion) {
+ // Do not open the file dialog in a hidden RenderView.
+ if (render_view_->is_hidden())
+ return false;
+
+ FileChooserParams ipc_params;
+ if (params.directory)
+ ipc_params.mode = FileChooserParams::UploadFolder;
+ else if (params.multiSelect)
+ ipc_params.mode = FileChooserParams::OpenMultiple;
+ else if (params.saveAs)
+ ipc_params.mode = FileChooserParams::Save;
+ else
+ ipc_params.mode = FileChooserParams::Open;
+ ipc_params.title = params.title;
+ ipc_params.default_file_name =
+ blink::WebStringToFilePath(params.initialValue).BaseName();
+ ipc_params.accept_types.reserve(params.acceptTypes.size());
+ for (size_t i = 0; i < params.acceptTypes.size(); ++i)
Avi (use Gerrit) 2016/06/10 21:52:54 for ( : )
nasko 2016/06/10 22:07:50 Done.
+ ipc_params.accept_types.push_back(params.acceptTypes[i]);
+ ipc_params.need_local_path = params.needLocalPath;
+#if defined(OS_ANDROID)
+ ipc_params.capture = params.useMediaCapture;
+#endif
+ ipc_params.requestor = params.requestor;
+
+ return ScheduleFileChooser(ipc_params, chooser_completion);
+}
+
void RenderFrameImpl::showContextMenu(const blink::WebContextMenuData& data) {
ContextMenuParams params = ContextMenuParamsBuilder::Build(data);
blink::WebRect position_in_window(params.x, params.y, 0, 0);
@@ -5129,6 +5206,43 @@ void RenderFrameImpl::OnSuppressFurtherDialogs() {
suppress_further_dialogs_ = true;
}
+void RenderFrameImpl::OnFileChooserResponse(
+ const std::vector<content::FileChooserFileInfo>& files) {
+ // This could happen if we navigated to a different page before the user
+ // closed the chooser.
+ if (file_chooser_completions_.empty())
+ return;
+
+ // Convert Chrome's SelectedFileInfo list to WebKit's.
+ WebVector<blink::WebFileChooserCompletion::SelectedFileInfo> selected_files(
+ files.size());
+ for (size_t i = 0; i < files.size(); ++i) {
Avi (use Gerrit) 2016/06/10 21:52:54 for ( : )
nasko 2016/06/10 22:07:49 This one uses i for the WebVector access, so I kep
+ blink::WebFileChooserCompletion::SelectedFileInfo selected_file;
+ selected_file.path = files[i].file_path.AsUTF16Unsafe();
+ selected_file.displayName =
+ base::FilePath(files[i].display_name).AsUTF16Unsafe();
+ if (files[i].file_system_url.is_valid()) {
+ selected_file.fileSystemURL = files[i].file_system_url;
+ selected_file.length = files[i].length;
+ selected_file.modificationTime = files[i].modification_time.ToDoubleT();
+ selected_file.isDirectory = files[i].is_directory;
+ }
+ selected_files[i] = selected_file;
+ }
+
+ if (file_chooser_completions_.front()->completion) {
+ file_chooser_completions_.front()->completion->didChooseFile(
+ selected_files);
+ }
+ file_chooser_completions_.pop_front();
+
+ // If there are more pending file chooser requests, schedule one now.
+ if (!file_chooser_completions_.empty()) {
+ Send(new FrameHostMsg_RunFileChooser(
+ routing_id_, file_chooser_completions_.front()->params));
+ }
+}
+
#if defined(OS_ANDROID)
void RenderFrameImpl::OnActivateNearestFindResult(int request_id,
float x,

Powered by Google App Engine
This is Rietveld 408576698