summaryrefslogtreecommitdiffstats
path: root/content/browser/browser_plugin
diff options
context:
space:
mode:
authorlazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-03 09:01:54 +0000
committerlazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-03 09:01:54 +0000
commitf85f5037bcba6e52fedae883add00b39f824edc3 (patch)
tree60a6c3fd2830a90d7c18fc6700f1d144bba04ef3 /content/browser/browser_plugin
parent090374df3d55fbe4e173d78e43684aa93675063d (diff)
downloadchromium_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')
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.cc90
-rw-r--r--content/browser/browser_plugin/browser_plugin_guest.h18
-rw-r--r--content/browser/browser_plugin/browser_plugin_message_filter.h2
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;