Commit 0e188643 authored by gbillock@chromium.org's avatar gbillock@chromium.org

[Geolocation] Attach user gesture indicator to permission request call.

This enables permissions bubble policies that rely on user gesture signals for deciding when/how to show bubble UI for permission requests.

BUG=332115

Review URL: https://codereview.chromium.org/185813004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262963 0039d316-1c4b-4281-b951-d872f2087c98
parent 64768d48
......@@ -22,6 +22,7 @@ AwGeolocationPermissionContext::RequestGeolocationPermissionOnUIThread(
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
......@@ -40,6 +41,7 @@ AwGeolocationPermissionContext::RequestGeolocationPermission(
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
......@@ -51,6 +53,7 @@ AwGeolocationPermissionContext::RequestGeolocationPermission(
render_view_id,
bridge_id,
requesting_frame,
user_gesture,
callback));
}
......
......@@ -25,6 +25,7 @@ class AwGeolocationPermissionContext :
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) OVERRIDE;
virtual void CancelGeolocationPermissionRequest(
int render_process_id,
......@@ -41,6 +42,7 @@ class AwGeolocationPermissionContext :
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback);
void CancelGeolocationPermissionRequestOnUIThread(
......
......@@ -41,6 +41,7 @@ class GeolocationPermissionRequest : public PermissionBubbleRequest {
ChromeGeolocationPermissionContext* context,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback,
const std::string& display_languages);
virtual ~GeolocationPermissionRequest();
......@@ -60,6 +61,7 @@ class GeolocationPermissionRequest : public PermissionBubbleRequest {
ChromeGeolocationPermissionContext* context_;
PermissionRequestID id_;
GURL requesting_frame_;
bool user_gesture_;
base::Callback<void(bool)> callback_;
std::string display_languages_;
};
......@@ -68,11 +70,13 @@ GeolocationPermissionRequest::GeolocationPermissionRequest(
ChromeGeolocationPermissionContext* context,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback,
const std::string& display_languages)
: context_(context),
id_(id),
requesting_frame_(requesting_frame),
user_gesture_(user_gesture),
callback_(callback),
display_languages_(display_languages) {}
......@@ -92,8 +96,7 @@ base::string16 GeolocationPermissionRequest::GetMessageTextFragment() const {
}
bool GeolocationPermissionRequest::HasUserGesture() const {
// TODO(gbillock): plumb this through from GeolocationDispatcher.
return false;
return user_gesture_;
}
GURL GeolocationPermissionRequest::GetRequestingHostname() const {
......@@ -135,6 +138,7 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) {
GURL requesting_frame_origin = requesting_frame.GetOrigin();
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
......@@ -143,7 +147,7 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
base::Bind(
&ChromeGeolocationPermissionContext::RequestGeolocationPermission,
this, render_process_id, render_view_id, bridge_id,
requesting_frame_origin, callback));
requesting_frame_origin, user_gesture, callback));
return;
}
......@@ -193,7 +197,7 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
return;
}
DecidePermission(web_contents, id, requesting_frame_origin,
DecidePermission(web_contents, id, requesting_frame_origin, user_gesture,
embedder, "", callback);
}
......@@ -211,6 +215,7 @@ void ChromeGeolocationPermissionContext::DecidePermission(
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
const GURL& embedder,
const std::string& accept_button_label,
base::Callback<void(bool)> callback) {
......@@ -232,7 +237,7 @@ void ChromeGeolocationPermissionContext::DecidePermission(
PermissionBubbleManager* mgr =
PermissionBubbleManager::FromWebContents(web_contents);
mgr->AddRequest(new GeolocationPermissionRequest(
this, id, requesting_frame, callback,
this, id, requesting_frame, user_gesture, callback,
profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)));
} else {
// setting == ask. Prompt the user.
......
......@@ -32,6 +32,7 @@ class ChromeGeolocationPermissionContext
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) OVERRIDE;
virtual void CancelGeolocationPermissionRequest(
int render_process_id,
......@@ -68,6 +69,7 @@ class ChromeGeolocationPermissionContext
virtual void DecidePermission(content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
const GURL& embedder,
const std::string& accept_button_label,
base::Callback<void(bool)> callback);
......
......@@ -6,12 +6,16 @@
#include "base/prefs/pref_service.h"
#include "chrome/browser/android/google_location_settings_helper.h"
#include "chrome/browser/content_settings/permission_request_id.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
ChromeGeolocationPermissionContextAndroid::
PermissionRequestInfo::PermissionRequestInfo()
: id(0, 0, 0, 0),
user_gesture(false) {}
ChromeGeolocationPermissionContextAndroid::
ChromeGeolocationPermissionContextAndroid(Profile* profile)
: ChromeGeolocationPermissionContext(profile),
......@@ -25,23 +29,19 @@ ChromeGeolocationPermissionContextAndroid::
void ChromeGeolocationPermissionContextAndroid::ProceedDecidePermission(
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
const PermissionRequestInfo& info,
const std::string& accept_button_label,
base::Callback<void(bool)> callback) {
// Super class implementation expects everything in UI thread instead.
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
ChromeGeolocationPermissionContext::DecidePermission(
web_contents, id, requesting_frame, embedder,
accept_button_label, callback);
web_contents, info.id, info.requesting_frame, info.user_gesture,
info.embedder, accept_button_label, callback);
}
void ChromeGeolocationPermissionContextAndroid::CheckMasterLocation(
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
const PermissionRequestInfo& info,
base::Callback<void(bool)> callback) {
// Check to see if the feature in its entirety has been disabled.
// This must happen before other services (e.g. tabs, extensions)
......@@ -68,12 +68,11 @@ void ChromeGeolocationPermissionContextAndroid::CheckMasterLocation(
google_location_settings_helper_->GetAcceptButtonLabel(allow_label);
ui_closure = base::Bind(
&ChromeGeolocationPermissionContextAndroid::ProceedDecidePermission,
this, web_contents, id, requesting_frame, embedder,
accept_button_label, callback);
this, web_contents, info, accept_button_label, callback);
} else {
ui_closure = base::Bind(
&ChromeGeolocationPermissionContextAndroid::PermissionDecided,
this, id, requesting_frame, embedder, callback, false);
this, info.id, info.requesting_frame, info.embedder, callback, false);
}
// This method is executed from the BlockingPool, post the result
......@@ -86,17 +85,24 @@ void ChromeGeolocationPermissionContextAndroid::DecidePermission(
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
const GURL& embedder,
const std::string& accept_button_label,
base::Callback<void(bool)> callback) {
PermissionRequestInfo info;
info.id = id;
info.requesting_frame = requesting_frame;
info.user_gesture = user_gesture;
info.embedder = embedder;
// Called on the UI thread. However, do the work on a separate thread
// to avoid strict mode violation.
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
content::BrowserThread::PostBlockingPoolTask(FROM_HERE,
base::Bind(
&ChromeGeolocationPermissionContextAndroid::CheckMasterLocation,
this, web_contents, id, requesting_frame, embedder, callback));
this, web_contents, info, callback));
}
void ChromeGeolocationPermissionContextAndroid::PermissionDecided(
......@@ -110,8 +116,8 @@ void ChromeGeolocationPermissionContextAndroid::PermissionDecided(
// the infobar to go back to the 'settings' to turn it back on.
if (allowed &&
!google_location_settings_helper_->IsGoogleAppsLocationSettingEnabled()) {
QueueController()->CreateInfoBarRequest(id, requesting_frame, embedder, "",
callback);
QueueController()->CreateInfoBarRequest(
id, requesting_frame, embedder, "", callback);
return;
}
......
......@@ -5,7 +5,9 @@
#ifndef CHROME_BROWSER_GEOLOCATION_CHROME_GEOLOCATION_PERMISSION_CONTEXT_ANDROID_H_
#define CHROME_BROWSER_GEOLOCATION_CHROME_GEOLOCATION_PERMISSION_CONTEXT_ANDROID_H_
#include "chrome/browser/content_settings/permission_request_id.h"
#include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
#include "url/gurl.h"
namespace content {
class WebContents;
......@@ -21,6 +23,15 @@ class ChromeGeolocationPermissionContextAndroid
explicit ChromeGeolocationPermissionContextAndroid(Profile* profile);
private:
struct PermissionRequestInfo {
PermissionRequestInfo();
PermissionRequestID id;
GURL requesting_frame;
bool user_gesture;
GURL embedder;
};
friend class ChromeGeolocationPermissionContext;
virtual ~ChromeGeolocationPermissionContextAndroid();
......@@ -29,6 +40,7 @@ class ChromeGeolocationPermissionContextAndroid
virtual void DecidePermission(content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture,
const GURL& embedder,
const std::string& accept_button_label,
base::Callback<void(bool)> callback) OVERRIDE;
......@@ -40,9 +52,7 @@ class ChromeGeolocationPermissionContextAndroid
bool allowed) OVERRIDE;
void ProceedDecidePermission(content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
const PermissionRequestInfo& info,
const std::string& accept_button_label,
base::Callback<void(bool)> callback);
......@@ -50,9 +60,7 @@ class ChromeGeolocationPermissionContextAndroid
private:
void CheckMasterLocation(content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
const PermissionRequestInfo& info,
base::Callback<void(bool)> callback);
DISALLOW_COPY_AND_ASSIGN(ChromeGeolocationPermissionContextAndroid);
......
......@@ -161,7 +161,7 @@ void GeolocationPermissionContextTests::RequestGeolocationPermission(
const GURL& requesting_frame) {
geolocation_permission_context_->RequestGeolocationPermission(
id.render_process_id(), id.render_view_id(), id.bridge_id(),
requesting_frame,
requesting_frame, false,
base::Bind(&GeolocationPermissionContextTests::PermissionResponse,
base::Unretained(this), id));
content::BrowserThread::GetBlockingPool()->FlushForTesting();
......
......@@ -26,6 +26,7 @@ void BrowserPluginGeolocationPermissionContext::RequestGeolocationPermission(
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
......@@ -38,6 +39,7 @@ void BrowserPluginGeolocationPermissionContext::RequestGeolocationPermission(
render_view_id,
bridge_id,
requesting_frame,
user_gesture,
callback));
return;
}
......@@ -56,6 +58,7 @@ void BrowserPluginGeolocationPermissionContext::RequestGeolocationPermission(
BrowserPluginGuest* guest = guest_web_contents->GetBrowserPluginGuest();
guest->AskEmbedderForGeolocationPermission(bridge_id,
requesting_frame,
user_gesture,
callback);
}
}
......
......@@ -26,6 +26,7 @@ class BrowserPluginGeolocationPermissionContext :
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) OVERRIDE;
virtual void CancelGeolocationPermissionRequest(
int render_process_id,
......
......@@ -112,10 +112,12 @@ class BrowserPluginGuest::GeolocationRequest : public PermissionRequest {
public:
GeolocationRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
GeolocationCallback callback,
int bridge_id)
int bridge_id,
bool user_gesture)
: PermissionRequest(guest),
callback_(callback),
bridge_id_(bridge_id) {
bridge_id_(bridge_id),
user_gesture_(user_gesture) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Geolocation"));
}
......@@ -145,6 +147,7 @@ class BrowserPluginGuest::GeolocationRequest : public PermissionRequest {
// permission. Therefore we use an invalid |bridge_id|.
-1 /* bridge_id */,
web_contents->GetLastCommittedURL(),
user_gesture_,
geolocation_callback);
return;
}
......@@ -157,6 +160,7 @@ class BrowserPluginGuest::GeolocationRequest : public PermissionRequest {
virtual ~GeolocationRequest() {}
base::Callback<void(bool)> callback_;
int bridge_id_;
bool user_gesture_;
};
class BrowserPluginGuest::MediaRequest : public PermissionRequest {
......@@ -1057,6 +1061,7 @@ void BrowserPluginGuest::SetDelegate(BrowserPluginGuestDelegate* delegate) {
void BrowserPluginGuest::AskEmbedderForGeolocationPermission(
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
const GeolocationCallback& callback) {
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kURL,
......@@ -1066,7 +1071,8 @@ void BrowserPluginGuest::AskEmbedderForGeolocationPermission(
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_GEOLOCATION,
new GeolocationRequest(weak_ptr_factory_.GetWeakPtr(),
callback,
bridge_id),
bridge_id,
user_gesture),
request_info);
DCHECK(bridge_id_to_request_id_map_.find(bridge_id) ==
......
......@@ -292,6 +292,7 @@ class CONTENT_EXPORT BrowserPluginGuest
// Requests geolocation permission through Embedder JavaScript API.
void AskEmbedderForGeolocationPermission(int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
const GeolocationCallback& callback);
// Cancels pending geolocation request.
void CancelGeolocationRequest(int bridge_id);
......
......@@ -103,7 +103,8 @@ class GeolocationDispatcherHostImpl : public GeolocationDispatcherHost {
void OnRequestPermission(int render_view_id,
int bridge_id,
const GURL& requesting_frame);
const GURL& requesting_frame,
bool user_gesture);
void OnCancelPermissionRequest(int render_view_id,
int bridge_id,
const GURL& requesting_frame);
......@@ -203,7 +204,8 @@ void GeolocationDispatcherHostImpl::OnLocationUpdate(
void GeolocationDispatcherHostImpl::OnRequestPermission(
int render_view_id,
int bridge_id,
const GURL& requesting_frame) {
const GURL& requesting_frame,
bool user_gesture) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
<< render_view_id << ":" << bridge_id;
......@@ -213,6 +215,7 @@ void GeolocationDispatcherHostImpl::OnRequestPermission(
render_view_id,
bridge_id,
requesting_frame,
user_gesture,
base::Bind(&SendGeolocationPermissionResponse,
render_process_id_,
render_view_id,
......
......@@ -45,10 +45,11 @@ IPC_MESSAGE_ROUTED1(GeolocationMsg_PositionUpdated,
// The |render_view_id| and |bridge_id| representing |host| is requesting
// permission to access geolocation position.
// This will be replied by GeolocationMsg_PermissionSet.
IPC_MESSAGE_CONTROL3(GeolocationHostMsg_RequestPermission,
IPC_MESSAGE_CONTROL4(GeolocationHostMsg_RequestPermission,
int /* render_view_id */,
int /* bridge_id */,
GURL /* GURL of the frame requesting geolocation */)
GURL /* GURL of the frame requesting geolocation */,
bool /* user_gesture */)
// The |render_view_id| and |bridge_id| representing |GURL| is cancelling its
// previous permission request to access geolocation position.
......
......@@ -27,6 +27,7 @@ class CONTENT_EXPORT GeolocationPermissionContext
int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) = 0;
// The renderer is cancelling a pending permission request.
......
......@@ -12,6 +12,7 @@
#include "third_party/WebKit/public/web/WebGeolocationClient.h"
#include "third_party/WebKit/public/web/WebGeolocationPosition.h"
#include "third_party/WebKit/public/web/WebGeolocationError.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
using blink::WebGeolocationController;
using blink::WebGeolocationError;
......@@ -89,7 +90,8 @@ void GeolocationDispatcher::requestPermission(
int bridge_id = pending_permissions_->add(permissionRequest);
base::string16 origin = permissionRequest.securityOrigin().toString();
Send(new GeolocationHostMsg_RequestPermission(
routing_id(), bridge_id, GURL(origin)));
routing_id(), bridge_id, GURL(origin),
blink::WebUserGestureIndicator::isProcessingUserGesture()));
}
// TODO(jknotten): Change the messages to use a security origin, so no
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment