diff options
author | lazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-03 09:01:54 +0000 |
---|---|---|
committer | lazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-03 09:01:54 +0000 |
commit | f85f5037bcba6e52fedae883add00b39f824edc3 (patch) | |
tree | 60a6c3fd2830a90d7c18fc6700f1d144bba04ef3 /content/browser/browser_plugin | |
parent | 090374df3d55fbe4e173d78e43684aa93675063d (diff) | |
download | chromium_src-f85f5037bcba6e52fedae883add00b39f824edc3.zip chromium_src-f85f5037bcba6e52fedae883add00b39f824edc3.tar.gz chromium_src-f85f5037bcba6e52fedae883add00b39f824edc3.tar.bz2 |
permissionrequest API for guest Download.
Exposed event:
event.type = 'download'
event.requestMethod = 'GET'/'POST'...
event.url = url
BUG=141204
TEST=Pending: osx + win (b/c there is a *ViewGuest change).
Added browser_tests:WebViewTest.Download, ran unit_tests:DownloadRequestLimiterTest*
Review URL: https://chromiumcodereview.appspot.com/13037003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192029 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/browser_plugin')
3 files changed, 97 insertions, 13 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; |