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

Unified Diff: chrome/browser/guestview/webview/webview_guest.cc

Issue 235633002: <webview>: Move Geolocation permission to chrome layer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed tests in Debug mode Created 6 years, 8 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: chrome/browser/guestview/webview/webview_guest.cc
diff --git a/chrome/browser/guestview/webview/webview_guest.cc b/chrome/browser/guestview/webview/webview_guest.cc
index a57a445e5dc99288c4e68244b08519da1159852d..fc82fbbe3e9996565e6133f8617233d06cab346d 100644
--- a/chrome/browser/guestview/webview/webview_guest.cc
+++ b/chrome/browser/guestview/webview/webview_guest.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/guestview/webview/webview_guest.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/web_request/web_request_api.h"
@@ -18,6 +19,7 @@
#include "chrome/browser/guestview/webview/webview_permission_types.h"
#include "chrome/common/chrome_version_info.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/geolocation_permission_context.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
@@ -75,8 +77,6 @@ static std::string PermissionTypeToString(BrowserPluginPermissionType type) {
switch (type) {
case BROWSER_PLUGIN_PERMISSION_TYPE_DOWNLOAD:
return webview::kPermissionTypeDownload;
- case BROWSER_PLUGIN_PERMISSION_TYPE_GEOLOCATION:
- return webview::kPermissionTypeGeolocation;
case BROWSER_PLUGIN_PERMISSION_TYPE_MEDIA:
return webview::kPermissionTypeMedia;
case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW:
@@ -91,6 +91,8 @@ static std::string PermissionTypeToString(BrowserPluginPermissionType type) {
default: {
WebViewPermissionType webview = static_cast<WebViewPermissionType>(type);
switch (webview) {
+ case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
+ return webview::kPermissionTypeGeolocation;
case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
return webview::kPermissionTypeLoadPlugin;
}
@@ -193,10 +195,6 @@ void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info,
content::RecordAction(
UserMetricsAction("BrowserPlugin.PermissionAllow.Download"));
break;
- case BROWSER_PLUGIN_PERMISSION_TYPE_GEOLOCATION:
- content::RecordAction(
- UserMetricsAction("BrowserPlugin.PermissionAllow.Geolocation"));
- break;
case BROWSER_PLUGIN_PERMISSION_TYPE_MEDIA:
content::RecordAction(
UserMetricsAction("BrowserPlugin.PermissionAllow.Media"));
@@ -219,6 +217,10 @@ void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info,
WebViewPermissionType webview_permission_type =
static_cast<WebViewPermissionType>(info.permission_type);
switch (webview_permission_type) {
+ case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
+ content::RecordAction(
+ UserMetricsAction("WebView.PermissionAllow.Geolocation"));
+ break;
case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
content::RecordAction(
UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad"));
@@ -234,10 +236,6 @@ void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info,
content::RecordAction(
UserMetricsAction("BrowserPlugin.PermissionDeny.Download"));
break;
- case BROWSER_PLUGIN_PERMISSION_TYPE_GEOLOCATION:
- content::RecordAction(
- UserMetricsAction("BrowserPlugin.PermissionDeny.Geolocation"));
- break;
case BROWSER_PLUGIN_PERMISSION_TYPE_MEDIA:
content::RecordAction(
UserMetricsAction("BrowserPlugin.PermissionDeny.Media"));
@@ -260,6 +258,10 @@ void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info,
WebViewPermissionType webview_permission_type =
static_cast<WebViewPermissionType>(info.permission_type);
switch (webview_permission_type) {
+ case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
+ content::RecordAction(
+ UserMetricsAction("WebView.PermissionDeny.Geolocation"));
+ break;
case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
content::RecordAction(
UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad"));
@@ -437,43 +439,15 @@ void WebViewGuest::RendererUnresponsive() {
DispatchEvent(new GuestView::Event(webview::kEventUnresponsive, args.Pass()));
}
-bool WebViewGuest::RequestPermission(
+void WebViewGuest::RequestPermission(
BrowserPluginPermissionType permission_type,
const base::DictionaryValue& request_info,
const PermissionResponseCallback& callback,
bool allowed_by_default) {
- // If there are too many pending permission requests then reject this request.
- if (pending_permission_requests_.size() >=
- webview::kMaxOutstandingPermissionRequests) {
- callback.Run(false, std::string());
- return true;
- }
-
- int request_id = next_permission_request_id_++;
- pending_permission_requests_[request_id] =
- PermissionResponseInfo(callback, permission_type, allowed_by_default);
- scoped_ptr<base::DictionaryValue> args(request_info.DeepCopy());
- args->SetInteger(webview::kRequestId, request_id);
- switch (permission_type) {
- case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: {
- DispatchEvent(new GuestView::Event(webview::kEventNewWindow,
- args.Pass()));
- break;
- }
- case BROWSER_PLUGIN_PERMISSION_TYPE_JAVASCRIPT_DIALOG: {
- DispatchEvent(new GuestView::Event(webview::kEventDialog,
- args.Pass()));
- break;
- }
- default: {
- args->SetString(webview::kPermission,
- PermissionTypeToString(permission_type));
- DispatchEvent(new GuestView::Event(webview::kEventPermissionRequest,
- args.Pass()));
- break;
- }
- }
- return true;
+ RequestPermissionInternal(permission_type,
+ request_info,
+ callback,
+ allowed_by_default);
}
void WebViewGuest::Observe(int type,
@@ -544,6 +518,78 @@ void WebViewGuest::Reload() {
guest_web_contents()->GetController().Reload(false);
}
+
+void WebViewGuest::RequestGeolocationPermission(
+ int bridge_id,
+ const GURL& requesting_frame,
+ bool user_gesture,
+ const base::Callback<void(bool)>& callback) {
+ base::DictionaryValue request_info;
+ request_info.Set(guestview::kUrl,
+ base::Value::CreateStringValue(requesting_frame.spec()));
+ request_info.Set(guestview::kUserGesture,
+ base::Value::CreateBooleanValue(user_gesture));
+
+ // It is safe to hold an unretained pointer to WebViewGuest because this
+ // callback is called from WebViewGuest::SetPermission.
+ const PermissionResponseCallback permission_callback =
+ base::Bind(&WebViewGuest::OnWebViewGeolocationPermissionResponse,
+ base::Unretained(this),
+ bridge_id,
+ user_gesture,
+ callback);
+ int request_id = RequestPermissionInternal(
+ static_cast<BrowserPluginPermissionType>(
+ WEB_VIEW_PERMISSION_TYPE_GEOLOCATION),
+ request_info,
+ permission_callback,
+ false /* allowed_by_default */);
+ bridge_id_to_request_id_map_[bridge_id] = request_id;
+}
+
+void WebViewGuest::OnWebViewGeolocationPermissionResponse(
+ int bridge_id,
+ bool user_gesture,
+ const base::Callback<void(bool)>& callback,
+ bool allow,
+ const std::string& user_input) {
+ // The <webview> embedder has allowed the permission. We now need to make sure
+ // that the embedder has geolocation permission.
+ RemoveBridgeID(bridge_id);
+
+ if (!allow || !attached()) {
+ callback.Run(false);
+ return;
+ }
+
+ content::GeolocationPermissionContext* geolocation_context =
+ browser_context()->GetGeolocationPermissionContext();
+
+ DCHECK(geolocation_context);
+ geolocation_context->RequestGeolocationPermission(
+ embedder_web_contents()->GetRenderProcessHost()->GetID(),
+ embedder_web_contents()->GetRoutingID(),
+ // The geolocation permission request here is not initiated
+ // through WebGeolocationPermissionRequest. We are only interested
+ // in the fact whether the embedder/app has geolocation
+ // permission. Therefore we use an invalid |bridge_id|.
+ -1 /* bridge_id */,
+ embedder_web_contents()->GetLastCommittedURL(),
+ user_gesture,
+ callback);
+}
+
+void WebViewGuest::CancelGeolocationPermissionRequest(int bridge_id) {
+ int request_id = RemoveBridgeID(bridge_id);
+ RequestMap::iterator request_itr =
+ pending_permission_requests_.find(request_id);
+
+ if (request_itr == pending_permission_requests_.end())
+ return;
+
+ pending_permission_requests_.erase(request_itr);
+}
+
WebViewGuest::SetPermissionResult WebViewGuest::SetPermission(
int request_id,
PermissionResponseAction action,
@@ -818,6 +864,65 @@ void WebViewGuest::InjectChromeVoxIfNeeded(
#endif
}
+int WebViewGuest::RemoveBridgeID(int bridge_id) {
+ std::map<int, int>::iterator bridge_itr =
+ bridge_id_to_request_id_map_.find(bridge_id);
+ if (bridge_itr == bridge_id_to_request_id_map_.end())
+ return webview::kInvalidPermissionRequestID;
+
+ int request_id = bridge_itr->second;
+ bridge_id_to_request_id_map_.erase(bridge_itr);
+ return request_id;
+}
+
+int WebViewGuest::RequestPermissionInternal(
+ BrowserPluginPermissionType permission_type,
+ const base::DictionaryValue& request_info,
+ const PermissionResponseCallback& callback,
+ bool allowed_by_default) {
+ // If there are too many pending permission requests then reject this request.
+ if (pending_permission_requests_.size() >=
+ webview::kMaxOutstandingPermissionRequests) {
+ // Let the stack unwind before we deny the permission request so that
+ // objects held by the permission request are not destroyed immediately
+ // after creation. This is to allow those same objects to be accessed again
+ // in the same scope without fear of use after freeing.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&PermissionResponseCallback::Run,
+ base::Owned(new PermissionResponseCallback(callback)),
+ allowed_by_default,
+ std::string()));
+ return webview::kInvalidPermissionRequestID;
+ }
+
+ int request_id = next_permission_request_id_++;
+ pending_permission_requests_[request_id] =
+ PermissionResponseInfo(callback, permission_type, allowed_by_default);
+ scoped_ptr<base::DictionaryValue> args(request_info.DeepCopy());
+ args->SetInteger(webview::kRequestId, request_id);
+ switch (permission_type) {
+ case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: {
+ DispatchEvent(new GuestView::Event(webview::kEventNewWindow,
+ args.Pass()));
+ break;
+ }
+ case BROWSER_PLUGIN_PERMISSION_TYPE_JAVASCRIPT_DIALOG: {
+ DispatchEvent(new GuestView::Event(webview::kEventDialog,
+ args.Pass()));
+ break;
+ }
+ default: {
+ args->SetString(webview::kPermission,
+ PermissionTypeToString(permission_type));
+ DispatchEvent(new GuestView::Event(webview::kEventPermissionRequest,
+ args.Pass()));
+ break;
+ }
+ }
+ return request_id;
+}
+
WebViewGuest::PermissionResponseInfo::PermissionResponseInfo()
: permission_type(BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN),
allowed_by_default(false) {
« no previous file with comments | « chrome/browser/guestview/webview/webview_guest.h ('k') | chrome/browser/guestview/webview/webview_permission_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698