diff options
Diffstat (limited to 'content')
10 files changed, 126 insertions, 28 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 4d7dfd5..6240790 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -13,6 +13,8 @@ #include "content/browser/browser_plugin/browser_plugin_guest_helper.h" #include "content/browser/browser_plugin/browser_plugin_guest_manager.h" #include "content/browser/browser_plugin/browser_plugin_host_factory.h" +#include "content/browser/browser_thread_impl.h" +#include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -37,6 +39,7 @@ #include "content/public/common/media_stream_request.h" #include "content/public/common/result_codes.h" #include "net/base/net_errors.h" +#include "net/url_request/url_request.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" #include "ui/surface/transport_dib.h" #include "webkit/glue/resource_type.h" @@ -77,6 +80,21 @@ static std::string WindowOpenDispositionToString( } } +// Called on IO thread. +static std::string RetrieveDownloadURLFromRequestId( + RenderViewHost* render_view_host, + int url_request_id) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + int render_process_id = render_view_host->GetProcess()->GetID(); + GlobalRequestID global_id(render_process_id, url_request_id); + net::URLRequest* url_request = + ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id); + if (url_request) + return url_request->url().possibly_invalid_spec(); + return ""; +} + } class BrowserPluginGuest::EmbedderRenderViewHostObserver @@ -309,14 +327,32 @@ void BrowserPluginGuest::AddNewContents(WebContents* source, disposition, initial_pos, user_gesture); } -bool BrowserPluginGuest::CanDownload(RenderViewHost* render_view_host, - int request_id, - const std::string& request_method) { - // TODO(fsamuel): We disable downloads in guests for now, but we will later - // expose API to allow embedders to handle them. - // Note: it seems content_shell ignores this. This should be fixed - // for debugging and test purposes. - return false; +void BrowserPluginGuest::CanDownload( + RenderViewHost* render_view_host, + int request_id, + const std::string& request_method, + const base::Callback<void(bool)>& callback) { + if (download_request_callback_map_.size() >= + kNumMaxOutstandingPermissionRequests) { + // Deny the download request. + callback.Run(false); + return; + } + + // TODO(lazyboy): Remove download specific map + // |download_request_callback_map_| once we have generalized request items for + // all permission types. + int permission_request_id = next_permission_request_id_++; + download_request_callback_map_[permission_request_id] = callback; + + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::IO, FROM_HERE, + base::Bind(&RetrieveDownloadURLFromRequestId, + render_view_host, request_id), + base::Bind(&BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId, + weak_ptr_factory_.GetWeakPtr(), + request_method, + permission_request_id)); } bool BrowserPluginGuest::HandleContextMenu( @@ -958,6 +994,9 @@ void BrowserPluginGuest::OnRespondPermission( int request_id, bool should_allow) { switch (permission_type) { + case BrowserPluginPermissionTypeDownload: + OnRespondPermissionDownload(request_id, should_allow); + break; case BrowserPluginPermissionTypeGeolocation: OnRespondPermissionGeolocation(request_id, should_allow); break; @@ -1170,6 +1209,20 @@ void BrowserPluginGuest::OnUpdateRect( new BrowserPluginMsg_UpdateRect(instance_id(), relay_params)); } +void BrowserPluginGuest::OnRespondPermissionDownload(int request_id, + bool should_allow) { + DownloadRequestMap::iterator download_request_iter = + download_request_callback_map_.find(request_id); + if (download_request_iter == download_request_callback_map_.end()) { + LOG(INFO) << "Not a valid request ID."; + return; + } + + const base::Callback<void(bool)>& can_download_callback = + download_request_iter->second; + can_download_callback.Run(should_allow); +} + void BrowserPluginGuest::OnRespondPermissionGeolocation( int request_id, bool should_allow) { if (should_allow && embedder_web_contents_) { @@ -1249,4 +1302,25 @@ void BrowserPluginGuest::OnRespondPermissionNewWindow( new_window_request_map_.erase(new_window_request_iter); } +void BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId( + const std::string& request_method, + int permission_request_id, + const std::string& url) { + if (url.empty()) { + OnRespondPermissionDownload(permission_request_id, + false /* should_allow */); + return; + } + + base::DictionaryValue request_info; + request_info.Set(browser_plugin::kRequestMethod, + base::Value::CreateStringValue(request_method)); + request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url)); + + SendMessageToEmbedder( + new BrowserPluginMsg_RequestPermission(instance_id(), + BrowserPluginPermissionTypeDownload, permission_request_id, + request_info)); +} + } // namespace content diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index aaa2cc9..605cafc 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h @@ -172,9 +172,10 @@ class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked) OVERRIDE; - virtual bool CanDownload(RenderViewHost* render_view_host, + virtual void CanDownload(RenderViewHost* render_view_host, int request_id, - const std::string& request_method) OVERRIDE; + const std::string& request_method, + const base::Callback<void(bool)>& callback) OVERRIDE; virtual bool HandleContextMenu(const ContextMenuParams& params) OVERRIDE; virtual void WebContentsCreated(WebContents* source_contents, int64 source_frame_id, @@ -219,7 +220,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver, void Attach(WebContentsImpl* embedder_web_contents, BrowserPluginHostMsg_CreateGuest_Params params); - // Requests geolocation permission through embedder js api. + // Requests geolocation permission through Embedder JavaScript API. void AskEmbedderForGeolocationPermission(int bridge_id, const GURL& requesting_frame, const GeolocationCallback& callback); @@ -228,6 +229,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver, // Embedder sets permission to allow or deny geolocation request. void SetGeolocationPermission(int request_id, bool allowed); + // Allow the embedder to call this for unhandled messages when // BrowserPluginGuest is already destroyed. static void AcknowledgeBufferPresent(int route_id, @@ -388,10 +390,17 @@ class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver, void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params); // Helpers for |OnRespondPermission|. + void OnRespondPermissionDownload(int request_id, bool should_allow); void OnRespondPermissionGeolocation(int request_id, bool should_allow); void OnRespondPermissionMedia(int request_id, bool should_allow); void OnRespondPermissionNewWindow(int request_id, bool should_allow); + // Requests download permission through embedder JavaScript API after + // retrieving url information from IO thread. + void DidRetrieveDownloadURLFromRequestId(const std::string& request_method, + int permission_request_id, + const std::string& url); + // Weak pointer used to ask GeolocationPermissionContext about geolocation // permission. base::WeakPtrFactory<BrowserPluginGuest> weak_ptr_factory_; @@ -441,6 +450,9 @@ class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver, typedef std::map<int, int> NewWindowRequestMap; NewWindowRequestMap new_window_request_map_; + typedef std::map<int, base::Callback<void(bool)> > DownloadRequestMap; + DownloadRequestMap download_request_callback_map_; + DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest); }; diff --git a/content/browser/browser_plugin/browser_plugin_message_filter.h b/content/browser/browser_plugin/browser_plugin_message_filter.h index 327d2f8..829c1ba 100644 --- a/content/browser/browser_plugin/browser_plugin_message_filter.h +++ b/content/browser/browser_plugin/browser_plugin_message_filter.h @@ -7,8 +7,6 @@ #include "content/public/browser/browser_message_filter.h" -struct ViewHostMsg_CreateWindow_Params; - namespace content { class BrowserContext; diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc index 088ebfd..876f684 100644 --- a/content/browser/web_contents/web_contents_view_guest.cc +++ b/content/browser/web_contents/web_contents_view_guest.cc @@ -36,7 +36,7 @@ WebContentsViewGuest::~WebContentsViewGuest() { } gfx::NativeView WebContentsViewGuest::GetNativeView() const { - return NULL; + return platform_view_->GetNativeView(); } gfx::NativeView WebContentsViewGuest::GetContentNativeView() const { diff --git a/content/common/browser_plugin/browser_plugin_constants.cc b/content/common/browser_plugin/browser_plugin_constants.cc index f486917..dab2cab 100644 --- a/content/common/browser_plugin/browser_plugin_constants.cc +++ b/content/common/browser_plugin/browser_plugin_constants.cc @@ -62,6 +62,7 @@ const char kOldURL[] = "oldUrl"; const char kOldHeight[] = "oldHeight"; const char kOldWidth[] = "oldWidth"; const char kPermission[] = "permission"; +const char kPermissionTypeDownload[] = "download"; const char kPermissionTypeGeolocation[] = "geolocation"; const char kPermissionTypeMedia[] = "media"; const char kPermissionTypeNewWindow[] = "newwindow"; @@ -70,6 +71,7 @@ const char kPersistPrefix[] = "persist:"; const char kProcessId[] = "processId"; const char kReason[] = "reason"; const char kRequestId[] = "requestId"; +const char kRequestMethod[] = "requestMethod"; const char kTargetURL[] = "targetUrl"; const char kURL[] = "url"; const char kWindowID[] = "windowId"; diff --git a/content/common/browser_plugin/browser_plugin_constants.h b/content/common/browser_plugin/browser_plugin_constants.h index 3dc489d..ce96acb 100644 --- a/content/common/browser_plugin/browser_plugin_constants.h +++ b/content/common/browser_plugin/browser_plugin_constants.h @@ -63,6 +63,7 @@ extern const char kOldURL[]; extern const char kOldHeight[]; extern const char kOldWidth[]; extern const char kPermission[]; +extern const char kPermissionTypeDownload[]; extern const char kPermissionTypeGeolocation[]; extern const char kPermissionTypeMedia[]; extern const char kPermissionTypeNewWindow[]; @@ -71,6 +72,7 @@ extern const char kPersistPrefix[]; extern const char kProcessId[]; extern const char kReason[]; extern const char kRequestId[]; +extern const char kRequestMethod[]; extern const char kTargetURL[]; extern const char kURL[]; extern const char kUserGesture[]; diff --git a/content/common/browser_plugin/browser_plugin_message_enums.h b/content/common/browser_plugin/browser_plugin_message_enums.h index c4ea346..9fe045a 100644 --- a/content/common/browser_plugin/browser_plugin_message_enums.h +++ b/content/common/browser_plugin/browser_plugin_message_enums.h @@ -9,20 +9,24 @@ enum BrowserPluginPermissionType { // Unknown type of permission request. BrowserPluginPermissionTypeUnknown, - // New window requests. - // Note: Even though new windows don't use the permission API, the new window - // API is sufficiently similar that it's convenient to consider it a - // permission type for code reuse. - BrowserPluginPermissionTypeNewWindow, - - // Media access (audio/video) permission request type. - BrowserPluginPermissionTypeMedia, + // Download. + BrowserPluginPermissionTypeDownload, // Geolocation. BrowserPluginPermissionTypeGeolocation, + // Media access (audio/video) permission request type. + BrowserPluginPermissionTypeMedia, + // PointerLock BrowserPluginPermissionTypePointerLock, + + + // New window requests. + // Note: Even though new windows don't use the permission API, the new window + // API is sufficiently similar that it's convenient to consider it a + // permission type for code reuse. + BrowserPluginPermissionTypeNewWindow, }; #endif // CONTENT_COMMON_BROWSER_PLUGIN_BROWSER_PLUGIN_MESSAGE_ENUMS_H_ diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc index 7a4409d..db56c7e 100644 --- a/content/public/browser/web_contents_delegate.cc +++ b/content/public/browser/web_contents_delegate.cc @@ -69,10 +69,12 @@ int WebContentsDelegate::GetExtraRenderViewHeight() const { return 0; } -bool WebContentsDelegate::CanDownload(RenderViewHost* render_view_host, - int request_id, - const std::string& request_method) { - return true; +void WebContentsDelegate::CanDownload( + RenderViewHost* render_view_host, + int request_id, + const std::string& request_method, + const base::Callback<void(bool)>& callback) { + callback.Run(true); } bool WebContentsDelegate::HandleContextMenu( diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 6705514..7371bda 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h @@ -220,9 +220,11 @@ class CONTENT_EXPORT WebContentsDelegate { virtual void WebContentsFocused(WebContents* contents) {} // Asks the delegate if the given tab can download. - virtual bool CanDownload(RenderViewHost* render_view_host, + // Invoking the |callback| synchronously is OK. + virtual void CanDownload(RenderViewHost* render_view_host, int request_id, - const std::string& request_method); + const std::string& request_method, + const base::Callback<void(bool)>& callback); // Return much extra vertical space should be allotted to the // render view widget during various animations (e.g. infobar closing). diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 636d2f4..f5b0f37 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -95,6 +95,8 @@ static std::string GetInternalEventName(const char* event_name) { static std::string PermissionTypeToString(BrowserPluginPermissionType type) { switch (type) { + case BrowserPluginPermissionTypeDownload: + return browser_plugin::kPermissionTypeDownload; case BrowserPluginPermissionTypeGeolocation: return browser_plugin::kPermissionTypeGeolocation; case BrowserPluginPermissionTypeMedia: |