From 4ebe69f4f611e1eef0d8886b97abdae37687a14b Mon Sep 17 00:00:00 2001 From: mlamouri Date: Fri, 14 Nov 2014 09:25:21 -0800 Subject: [PATCH] Implement basic mojo Permission service and use it for Geolocation. This is implementing one side of the mojo Permission service: requesting a permission. This is being used by the Geolocation code in the renderer process. This CL is creating all the required hooks for the permission service and can be used as a base to increment on top of. BUG=430238, 420497 Review URL: https://codereview.chromium.org/722153003 Cr-Commit-Position: refs/heads/master@{#304227} --- .../browser/frame_host/render_frame_host_impl.cc | 9 ++ .../browser/frame_host/render_frame_host_impl.h | 4 + .../geolocation/geolocation_dispatcher_host.cc | 144 --------------------- .../geolocation/geolocation_dispatcher_host.h | 76 ----------- .../permissions/permission_service_context.cc | 63 +++++++++ .../permissions/permission_service_context.h | 51 ++++++++ .../browser/permissions/permission_service_impl.cc | 120 +++++++++++++++++ .../browser/permissions/permission_service_impl.h | 73 +++++++++++ .../renderer_host/render_process_host_impl.cc | 7 + .../renderer_host/render_process_host_impl.h | 4 + content/browser/web_contents/web_contents_impl.cc | 2 - content/browser/web_contents/web_contents_impl.h | 3 - content/common/BUILD.gn | 1 + content/common/content_message_generator.h | 1 - content/common/geolocation_messages.h | 46 ------- content/common/permission_service.mojom | 25 ++++ content/content_browser.gypi | 6 +- content/content_common.gypi | 1 - content/content_common_mojo_bindings.gypi | 1 + content/renderer/geolocation_dispatcher.cc | 47 ++++--- content/renderer/geolocation_dispatcher.h | 7 +- 21 files changed, 391 insertions(+), 300 deletions(-) delete mode 100644 content/browser/geolocation/geolocation_dispatcher_host.cc delete mode 100644 content/browser/geolocation/geolocation_dispatcher_host.h create mode 100644 content/browser/permissions/permission_service_context.cc create mode 100644 content/browser/permissions/permission_service_context.h create mode 100644 content/browser/permissions/permission_service_impl.cc create mode 100644 content/browser/permissions/permission_service_impl.h delete mode 100644 content/common/geolocation_messages.h create mode 100644 content/common/permission_service.mojom diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 6c61bda83347..4d497d73d551 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -25,6 +25,8 @@ #include "content/browser/frame_host/render_frame_proxy_host.h" #include "content/browser/frame_host/render_widget_host_view_child_frame.h" #include "content/browser/geolocation/geolocation_service_context.h" +#include "content/browser/permissions/permission_service_context.h" +#include "content/browser/permissions/permission_service_impl.h" #include "content/browser/renderer_host/input/input_router.h" #include "content/browser/renderer_host/input/timeout_monitor.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -1248,6 +1250,13 @@ void RenderFrameHostImpl::RegisterMojoServices() { base::Bind(&RenderFrameHostImpl::DidUseGeolocationPermission, base::Unretained(this)))); } + + if (!permission_service_context_) + permission_service_context_.reset(new PermissionServiceContext(this)); + + GetServiceRegistry()->AddService( + base::Bind(&PermissionServiceContext::CreateService, + base::Unretained(permission_service_context_.get()))); } void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) { diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 9bfcc060b12d..05d04fb2fecc 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h @@ -53,6 +53,7 @@ class CrossProcessFrameConnector; class CrossSiteTransferringRequest; class FrameTree; class FrameTreeNode; +class PermissionServiceContext; class RenderFrameHostDelegate; class RenderFrameProxyHost; class RenderProcessHost; @@ -605,6 +606,9 @@ class CONTENT_EXPORT RenderFrameHostImpl // response once it has started. scoped_ptr stream_handle_; + // Context shared for each PermissionService instance created for this RFH. + scoped_ptr permission_service_context_; + // NOTE: This must be the last member. base::WeakPtrFactory weak_ptr_factory_; diff --git a/content/browser/geolocation/geolocation_dispatcher_host.cc b/content/browser/geolocation/geolocation_dispatcher_host.cc deleted file mode 100644 index 9dfec900ea29..000000000000 --- a/content/browser/geolocation/geolocation_dispatcher_host.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/geolocation/geolocation_dispatcher_host.h" - -#include - -#include "base/bind.h" -#include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/browser/geolocation/geolocation_provider_impl.h" -#include "content/browser/renderer_host/render_message_filter.h" -#include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/content_browser_client.h" -#include "content/common/geolocation_messages.h" - -namespace content { - -GeolocationDispatcherHost::PendingPermission::PendingPermission( - int render_frame_id, - int render_process_id, - int bridge_id, - const GURL& origin) - : render_frame_id(render_frame_id), - render_process_id(render_process_id), - bridge_id(bridge_id), - origin(origin) { -} - -GeolocationDispatcherHost::PendingPermission::~PendingPermission() { -} - -GeolocationDispatcherHost::GeolocationDispatcherHost( - WebContents* web_contents) - : WebContentsObserver(web_contents), - weak_factory_(this) { - // This is initialized by WebContentsImpl. Do not add any non-trivial - // initialization here, defer to OnStartUpdating which is triggered whenever - // a javascript geolocation object is actually initialized. -} - -GeolocationDispatcherHost::~GeolocationDispatcherHost() { -} - -void GeolocationDispatcherHost::RenderFrameDeleted( - RenderFrameHost* render_frame_host) { - CancelPermissionRequestsForFrame(render_frame_host); -} - -void GeolocationDispatcherHost::DidNavigateAnyFrame( - RenderFrameHost* render_frame_host, - const LoadCommittedDetails& details, - const FrameNavigateParams& params) { - if (details.is_in_page) - return; - - CancelPermissionRequestsForFrame(render_frame_host); -} - -bool GeolocationDispatcherHost::OnMessageReceived( - const IPC::Message& msg, RenderFrameHost* render_frame_host) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(GeolocationDispatcherHost, msg, - render_frame_host) - IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission, - OnRequestPermission) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void GeolocationDispatcherHost::OnRequestPermission( - RenderFrameHost* render_frame_host, - int bridge_id, - const GURL& requesting_origin, - bool user_gesture) { - int render_process_id = render_frame_host->GetProcess()->GetID(); - int render_frame_id = render_frame_host->GetRoutingID(); - - PendingPermission pending_permission( - render_frame_id, render_process_id, bridge_id, requesting_origin); - pending_permissions_.push_back(pending_permission); - - GetContentClient()->browser()->RequestPermission( - content::PERMISSION_GEOLOCATION, - web_contents(), - bridge_id, - requesting_origin, - user_gesture, - base::Bind(&GeolocationDispatcherHost::SendGeolocationPermissionResponse, - weak_factory_.GetWeakPtr(), - render_process_id, - render_frame_id, - bridge_id)); -} - -void GeolocationDispatcherHost::SendGeolocationPermissionResponse( - int render_process_id, - int render_frame_id, - int bridge_id, - bool allowed) { - for (size_t i = 0; i < pending_permissions_.size(); ++i) { - if (pending_permissions_[i].render_process_id == render_process_id && - pending_permissions_[i].render_frame_id == render_frame_id && - pending_permissions_[i].bridge_id == bridge_id) { - RenderFrameHost* render_frame_host = - RenderFrameHost::FromID(render_process_id, render_frame_id); - if (render_frame_host) { - render_frame_host->Send(new GeolocationMsg_PermissionSet( - render_frame_id, bridge_id, allowed)); - } - - if (allowed) { - GeolocationProviderImpl::GetInstance()-> - UserDidOptIntoLocationServices(); - } - - pending_permissions_.erase(pending_permissions_.begin() + i); - return; - } - } - - NOTREACHED(); -} - -void GeolocationDispatcherHost::CancelPermissionRequestsForFrame( - RenderFrameHost* render_frame_host) { - int render_process_id = render_frame_host->GetProcess()->GetID(); - int render_frame_id = render_frame_host->GetRoutingID(); - - for (size_t i = 0; i < pending_permissions_.size(); ++i) { - if (pending_permissions_[i].render_process_id == render_process_id && - pending_permissions_[i].render_frame_id == render_frame_id) { - GetContentClient()->browser()->CancelPermissionRequest( - content::PERMISSION_GEOLOCATION, - web_contents(), - pending_permissions_[i].bridge_id, - pending_permissions_[i].origin); - pending_permissions_.erase(pending_permissions_.begin() + i); - } - } -} - -} // namespace content diff --git a/content/browser/geolocation/geolocation_dispatcher_host.h b/content/browser/geolocation/geolocation_dispatcher_host.h deleted file mode 100644 index 6359de10cceb..000000000000 --- a/content/browser/geolocation/geolocation_dispatcher_host.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_ -#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_ - -#include -#include - -#include "base/callback_forward.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/web_contents_observer.h" - -class GURL; - -namespace content { - -// GeolocationDispatcherHost is an observer for Geolocation permissions-related -// messages. In this role, it's the complement of GeolocationDispatcher (owned -// by RenderFrame). -// TODO(blundell): Eliminate this class in favor of having -// Mojo handle permissions for geolocation once there is resolution on how -// that will work. crbug.com/420498 -class GeolocationDispatcherHost : public WebContentsObserver { - public: - explicit GeolocationDispatcherHost(WebContents* web_contents); - ~GeolocationDispatcherHost() override; - - private: - // WebContentsObserver - void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; - void DidNavigateAnyFrame(RenderFrameHost* render_frame_host, - const LoadCommittedDetails& details, - const FrameNavigateParams& params) override; - bool OnMessageReceived(const IPC::Message& msg, - RenderFrameHost* render_frame_host) override; - - // Message handlers: - // TODO(mlamouri): |requesting_origin| should be a security origin to - // guarantee that a proper origin is passed. - void OnRequestPermission(RenderFrameHost* render_frame_host, - int bridge_id, - const GURL& requesting_origin, - bool user_gesture); - - void SendGeolocationPermissionResponse(int render_process_id, - int render_frame_id, - int bridge_id, - bool allowed); - - // Clear pending permissions associated with a given frame and request the - // browser to cancel the permission requests. - void CancelPermissionRequestsForFrame(RenderFrameHost* render_frame_host); - - struct PendingPermission { - PendingPermission(int render_frame_id, - int render_process_id, - int bridge_id, - const GURL& origin); - ~PendingPermission(); - int render_frame_id; - int render_process_id; - int bridge_id; - GURL origin; - }; - std::vector pending_permissions_; - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHost); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_ diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc new file mode 100644 index 000000000000..2c7e91b96845 --- /dev/null +++ b/content/browser/permissions/permission_service_context.cc @@ -0,0 +1,63 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/permissions/permission_service_context.h" + +#include "content/browser/permissions/permission_service_impl.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" + +namespace content { + +PermissionServiceContext::PermissionServiceContext( + RenderFrameHost* render_frame_host) + : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), + render_frame_host_(render_frame_host) { +} + +PermissionServiceContext::~PermissionServiceContext() { +} + +void PermissionServiceContext::CreateService( + mojo::InterfaceRequest request) { + PermissionServiceImpl* service = + new PermissionServiceImpl(this); + + services_.push_back(service); + mojo::WeakBindToRequest(service, &request); +} + +void PermissionServiceContext::ServiceHadConnectionError( + PermissionServiceImpl* service) { + auto it = std::find(services_.begin(), services_.end(), service); + DCHECK(it != services_.end()); + services_.erase(it); +} + +void PermissionServiceContext::RenderFrameDeleted( + RenderFrameHost* render_frame_host) { + CancelPendingRequests(render_frame_host); +} + +void PermissionServiceContext::DidNavigateAnyFrame( + RenderFrameHost* render_frame_host, + const LoadCommittedDetails& details, + const FrameNavigateParams& params) { + if (details.is_in_page) + return; + + CancelPendingRequests(render_frame_host); +} + +void PermissionServiceContext::CancelPendingRequests( + RenderFrameHost* render_frame_host) const { + if (render_frame_host != render_frame_host_) + return; + + for (auto* service : services_) + service->CancelPendingRequests(); +} + +} // namespace content diff --git a/content/browser/permissions/permission_service_context.h b/content/browser/permissions/permission_service_context.h new file mode 100644 index 000000000000..46d6b397026a --- /dev/null +++ b/content/browser/permissions/permission_service_context.h @@ -0,0 +1,51 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_PERMISSIONS_PERMISSION_SERVICE_CONTEXT_H_ +#define CONTENT_BROWSER_PERMISSIONS_PERMISSION_SERVICE_CONTEXT_H_ + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/interface_request.h" + +namespace content { + +class PermissionService; +class PermissionServiceImpl; +class RenderFrameHost; + +// Provides information to a PermissionService. It is used by the +// PermissionService to handle request permission UI. +// There is one PermissionServiceContext per RenderFrameHost/RenderProcessHost +// which owns it. It then owns all PermissionService associated to their owner. +class PermissionServiceContext : public WebContentsObserver { + public: + explicit PermissionServiceContext(RenderFrameHost* render_frame_host); + virtual ~PermissionServiceContext(); + + void CreateService(mojo::InterfaceRequest request); + + // Called by a PermissionService identified as |service| when it has a + // connection error in order to get unregistered and killed. + void ServiceHadConnectionError(PermissionServiceImpl* service); + + private: + // WebContentsObserver + void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; + void DidNavigateAnyFrame(RenderFrameHost* render_frame_host, + const LoadCommittedDetails& details, + const FrameNavigateParams& params) override; + + void CancelPendingRequests(RenderFrameHost*) const; + + RenderFrameHost* render_frame_host_; + ScopedVector services_; + + DISALLOW_COPY_AND_ASSIGN(PermissionServiceContext); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_PERMISSIONS_PERMISSION_SERVICE_CONTEXT_H_ diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc new file mode 100644 index 000000000000..a5f66bf2f547 --- /dev/null +++ b/content/browser/permissions/permission_service_impl.cc @@ -0,0 +1,120 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/permissions/permission_service_impl.h" + +#include "content/browser/geolocation/geolocation_provider_impl.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/render_process_host.h" + +namespace content { + +namespace { + +PermissionType PermissionNameToPermissionType(PermissionName name) { + switch(name) { + case PERMISSION_NAME_GEOLOCATION: + return PERMISSION_GEOLOCATION; + } + + NOTREACHED(); + return PERMISSION_NUM; +} + +} // anonymous namespace + +PermissionServiceImpl::PendingRequest::PendingRequest(PermissionType permission, + const GURL& origin) + : permission(permission), + origin(origin) { +} + +PermissionServiceImpl::PermissionServiceImpl(PermissionServiceContext* context) + : context_(context), + weak_factory_(this) { +} + +PermissionServiceImpl::~PermissionServiceImpl() { +} + +void PermissionServiceImpl::OnConnectionError() { + context_->ServiceHadConnectionError(this); + // After that call, |this| will be deleted. +} + +void PermissionServiceImpl::RequestPermission( + PermissionName permission, + const mojo::String& origin, + const mojo::Callback& callback) { + // This condition is valid if the call is coming from a ChildThread instead of + // a RenderFrame. Some consumers of the service run in Workers and some in + // Frames. In the context of a Worker, it is not possible to show a + // permission prompt because there is no tab. In the context of a Frame, we + // can. Even if the call comes from a context where it is not possible to show + // any UI, we want to still return something relevant so the current + // permission status is returned. + if (!context_->web_contents()) { + // There is no way to show a UI so the call will simply return the current + // permission. + HasPermission(permission, origin, callback); + return; + } + + PermissionType permission_type = PermissionNameToPermissionType(permission); + int request_id = pending_requests_.Add( + new PendingRequest(permission_type, GURL(origin))); + + GetContentClient()->browser()->RequestPermission( + permission_type, + context_->web_contents(), + request_id, + GURL(origin), + true, // TODO(mlamouri): should be removed, see http://crbug.com/423770 + base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, + weak_factory_.GetWeakPtr(), + callback, + request_id)); +} + +void PermissionServiceImpl::OnRequestPermissionResponse( + const mojo::Callback& callback, + int request_id, + bool allowed) { + // TODO(mlamouri): we might want a generic way to handle those things. + if (allowed && + pending_requests_.Lookup(request_id)->permission == + PERMISSION_GEOLOCATION) { + GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices(); + } + + pending_requests_.Remove(request_id); + + // TODO(mlamouri): for now, we only get a boolean back, but we would ideally + // need a ContentSetting, see http://crbug.com/432978 + callback.Run(allowed ? PERMISSION_STATUS_GRANTED : PERMISSION_STATUS_ASK); +} + +void PermissionServiceImpl::CancelPendingRequests() { + DCHECK(context_->web_contents()); + + for (RequestsMap::Iterator it(&pending_requests_); + !it.IsAtEnd(); it.Advance()) { + GetContentClient()->browser()->CancelPermissionRequest( + it.GetCurrentValue()->permission, + context_->web_contents(), + it.GetCurrentKey(), + it.GetCurrentValue()->origin); + } + + pending_requests_.Clear(); +} + +void PermissionServiceImpl::HasPermission( + PermissionName permission, + const mojo::String& origin, + const mojo::Callback& callback) { + NOTIMPLEMENTED(); +} + +} // namespace content diff --git a/content/browser/permissions/permission_service_impl.h b/content/browser/permissions/permission_service_impl.h new file mode 100644 index 000000000000..c67ae88ef1d1 --- /dev/null +++ b/content/browser/permissions/permission_service_impl.h @@ -0,0 +1,73 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_PERMISSIONS_PERMISSION_SERVICE_IMPL_H_ +#define CONTENT_BROWSER_PERMISSIONS_PERMISSION_SERVICE_IMPL_H_ + +#include "base/id_map.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "content/browser/permissions/permission_service_context.h" +#include "content/common/permission_service.mojom.h" +#include "content/public/browser/permission_type.h" + +namespace content { + +// Implements the PermissionService Mojo interface. +// This service can be created from a RenderFrameHost or a RenderProcessHost. +// It is owned by a PermissionServiceContext. +// It receives at PermissionServiceContext instance when created which allows it +// to have some information about the current context. That enables the service +// to know whether it can show UI and have knowledge of the associated +// WebContents for example. +class PermissionServiceImpl : public mojo::InterfaceImpl { + public: + virtual ~PermissionServiceImpl(); + + // Clear pending permissions associated with a given frame and request the + // browser to cancel the permission requests. + void CancelPendingRequests(); + + protected: + friend PermissionServiceContext; + + PermissionServiceImpl(PermissionServiceContext* context); + + private: + struct PendingRequest { + PendingRequest(PermissionType permission, const GURL& origin); + PermissionType permission; + GURL origin; + }; + typedef IDMap RequestsMap; + + // PermissionService. + void HasPermission( + PermissionName permission, + const mojo::String& origin, + const mojo::Callback& callback) override; + void RequestPermission( + PermissionName permission, + const mojo::String& origin, + const mojo::Callback& callback) override; + + // mojo::InterfaceImpl. + void OnConnectionError() override; + + void OnRequestPermissionResponse( + const mojo::Callback& callback, + int request_id, + bool allowed); + + RequestsMap pending_requests_; + // context_ owns |this|. + PermissionServiceContext* context_; + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PermissionServiceImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_PERMISSIONS_PERMISSION_SERVICE_IMPL_H_ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 079f6e9dda95..e11a6b71e91c 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -66,6 +66,8 @@ #include "content/browser/mime_registry_message_filter.h" #include "content/browser/mojo/mojo_application_host.h" #include "content/browser/notifications/notification_message_filter.h" +#include "content/browser/permissions/permission_service_context.h" +#include "content/browser/permissions/permission_service_impl.h" #include "content/browser/profiler_message_filter.h" #include "content/browser/push_messaging/push_messaging_message_filter.h" #include "content/browser/quota_dispatcher_host.h" @@ -448,6 +450,7 @@ RenderProcessHostImpl::RenderProcessHostImpl( within_process_died_observer_(false), power_monitor_broadcaster_(this), worker_ref_count_(0), + permission_service_context_(new PermissionServiceContext(nullptr)), weak_factory_(this) { widget_helper_ = new RenderWidgetHelper(); @@ -876,6 +879,10 @@ void RenderProcessHostImpl::CreateMessageFilters() { void RenderProcessHostImpl::RegisterMojoServices() { mojo_application_host_->service_registry()->AddService( base::Bind(&device::BatteryMonitorImpl::Create)); + + mojo_application_host_->service_registry()->AddService( + base::Bind(&PermissionServiceContext::CreateService, + base::Unretained(permission_service_context_.get()))); } int RenderProcessHostImpl::GetNextRoutingID() { diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index b3bdf3bea7fb..b4e77d4f247b 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h @@ -48,6 +48,7 @@ class NotificationMessageFilter; #if defined(ENABLE_WEBRTC) class P2PSocketDispatcherHost; #endif +class PermissionServiceContext; class PeerConnectionTrackerHost; class RendererMainThread; class RenderWidgetHelper; @@ -465,6 +466,9 @@ class CONTENT_EXPORT RenderProcessHostImpl // Records the time when the process starts surviving for workers for UMA. base::TimeTicks survive_for_worker_start_time_; + // Context shared for each PermissionService instance created for this RPH. + scoped_ptr permission_service_context_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 43bc9ea4417c..5ec31a02c056 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -35,7 +35,6 @@ #include "content/browser/frame_host/navigator_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/frame_host/render_widget_host_view_child_frame.h" -#include "content/browser/geolocation/geolocation_dispatcher_host.h" #include "content/browser/geolocation/geolocation_service_context.h" #include "content/browser/host_zoom_map_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" @@ -1189,7 +1188,6 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, NotificationService::AllBrowserContextsAndSources()); - geolocation_dispatcher_host_.reset(new GeolocationDispatcherHost(this)); midi_dispatcher_host_.reset(new MidiDispatcherHost(this)); screen_orientation_dispatcher_host_.reset( diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 49896cef95ab..665695d83390 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -51,7 +51,6 @@ class BrowserPluginGuest; class BrowserPluginGuestManager; class DateTimeChooserAndroid; class DownloadItem; -class GeolocationDispatcherHost; class GeolocationServiceContext; class InterstitialPageImpl; class JavaScriptDialogManager; @@ -1214,8 +1213,6 @@ class CONTENT_EXPORT WebContentsImpl scoped_ptr geolocation_service_context_; - scoped_ptr geolocation_dispatcher_host_; - scoped_ptr midi_dispatcher_host_; scoped_ptr diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index cfe291b724fd..559a719e5c9b 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn @@ -319,6 +319,7 @@ source_set("common") { mojom("mojo_bindings") { sources = [ "geolocation_service.mojom", + "permission_service.mojom", "render_frame_setup.mojom", ] diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h index c8ec407e6503..65837244247c 100644 --- a/content/common/content_message_generator.h +++ b/content/common/content_message_generator.h @@ -26,7 +26,6 @@ #include "content/common/frame_messages.h" #include "content/common/gamepad_messages.h" #include "content/common/geofencing_messages.h" -#include "content/common/geolocation_messages.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/image_messages.h" #include "content/common/indexed_db/indexed_db_messages.h" diff --git a/content/common/geolocation_messages.h b/content/common/geolocation_messages.h deleted file mode 100644 index b66a1919b798..000000000000 --- a/content/common/geolocation_messages.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// IPC messages for geolocation. -// Multiply-included message file, hence no include guard. - -#include "content/public/common/geoposition.h" -#include "ipc/ipc_message_macros.h" -#include "url/gurl.h" - -#define IPC_MESSAGE_START GeolocationMsgStart - -IPC_ENUM_TRAITS_MAX_VALUE(content::Geoposition::ErrorCode, - content::Geoposition::ERROR_CODE_LAST) - -IPC_STRUCT_TRAITS_BEGIN(content::Geoposition) - IPC_STRUCT_TRAITS_MEMBER(latitude) - IPC_STRUCT_TRAITS_MEMBER(longitude) - IPC_STRUCT_TRAITS_MEMBER(altitude) - IPC_STRUCT_TRAITS_MEMBER(accuracy) - IPC_STRUCT_TRAITS_MEMBER(altitude_accuracy) - IPC_STRUCT_TRAITS_MEMBER(heading) - IPC_STRUCT_TRAITS_MEMBER(speed) - IPC_STRUCT_TRAITS_MEMBER(timestamp) - IPC_STRUCT_TRAITS_MEMBER(error_code) - IPC_STRUCT_TRAITS_MEMBER(error_message) -IPC_STRUCT_TRAITS_END() - -// Messages sent from the browser to the renderer. - -// Reply in response to GeolocationHostMsg_RequestPermission. -IPC_MESSAGE_ROUTED2(GeolocationMsg_PermissionSet, - int /* bridge_id */, - bool /* is_allowed */) - -// Messages sent from the renderer to the browser. - -// The |bridge_id| representing |host| is requesting permission to access -// geolocation position. This will be replied by GeolocationMsg_PermissionSet. -// TODO(mlamouri): |origin| should be a security origin to guarantee that a -// proper origin is passed. -IPC_MESSAGE_ROUTED3(GeolocationHostMsg_RequestPermission, - int /* bridge_id */, - GURL /* origin in the frame requesting geolocation */, - bool /* user_gesture */) diff --git a/content/common/permission_service.mojom b/content/common/permission_service.mojom new file mode 100644 index 000000000000..a5734aaac68d --- /dev/null +++ b/content/common/permission_service.mojom @@ -0,0 +1,25 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module content; + +enum PermissionStatus { + GRANTED, + DENIED, + ASK +}; + +enum PermissionName { + GEOLOCATION, +}; + +// The Permission service provides permission handling capabilities by exposing +// methods to check, request, and revoke permissions. It also allows a client to +// start listening to permission changes. +interface PermissionService { + HasPermission(PermissionName permission, string origin) + => (PermissionStatus status); + RequestPermission(PermissionName permission, string origin) + => (PermissionStatus status); +}; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index b43ec6e1ab68..bd65c4837efc 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -673,8 +673,6 @@ 'browser/geofencing/geofencing_service.h', 'browser/geolocation/empty_wifi_data_provider.cc', 'browser/geolocation/empty_wifi_data_provider.h', - 'browser/geolocation/geolocation_dispatcher_host.cc', - 'browser/geolocation/geolocation_dispatcher_host.h', 'browser/geolocation/geolocation_provider_impl.cc', 'browser/geolocation/geolocation_provider_impl.h', 'browser/geolocation/geolocation_service_context.cc', @@ -932,6 +930,10 @@ 'browser/notifications/page_notification_delegate.h', 'browser/notification_service_impl.cc', 'browser/notification_service_impl.h', + 'browser/permissions/permission_service_context.cc', + 'browser/permissions/permission_service_context.h', + 'browser/permissions/permission_service_impl.cc', + 'browser/permissions/permission_service_impl.h', 'browser/power_monitor_message_broadcaster.cc', 'browser/power_monitor_message_broadcaster.h', 'browser/power_profiler/power_data_provider.h', diff --git a/content/content_common.gypi b/content/content_common.gypi index 4a091e7aa6aa..5f2ab23f1b91 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -248,7 +248,6 @@ 'common/geofencing_messages.h', 'common/geofencing_status.cc', 'common/geofencing_status.h', - 'common/geolocation_messages.h', 'common/gin_java_bridge_messages.h', 'common/gpu/client/command_buffer_proxy_impl.cc', 'common/gpu/client/command_buffer_proxy_impl.h', diff --git a/content/content_common_mojo_bindings.gypi b/content/content_common_mojo_bindings.gypi index da5c00a4d3d5..ebff805636ec 100644 --- a/content/content_common_mojo_bindings.gypi +++ b/content/content_common_mojo_bindings.gypi @@ -15,6 +15,7 @@ 'sources': [ # NOTE: Sources duplicated in //content/common/BUILD.gn:mojo_bindings. 'common/geolocation_service.mojom', + 'common/permission_service.mojom', 'common/render_frame_setup.mojom', # NOTE: Sources duplicated in diff --git a/content/renderer/geolocation_dispatcher.cc b/content/renderer/geolocation_dispatcher.cc index fde4fc98cba9..9eeca7118307 100644 --- a/content/renderer/geolocation_dispatcher.cc +++ b/content/renderer/geolocation_dispatcher.cc @@ -4,7 +4,8 @@ #include "content/renderer/geolocation_dispatcher.h" -#include "content/common/geolocation_messages.h" +#include "content/child/child_thread.h" +#include "content/public/common/geoposition.h" #include "content/renderer/render_view_impl.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/web/WebGeolocationPermissionRequest.h" @@ -30,15 +31,6 @@ GeolocationDispatcher::GeolocationDispatcher(RenderFrame* render_frame) GeolocationDispatcher::~GeolocationDispatcher() {} -bool GeolocationDispatcher::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcher, message) - IPC_MESSAGE_HANDLER(GeolocationMsg_PermissionSet, OnPermissionSet) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - void GeolocationDispatcher::startUpdating() { if (!geolocation_service_.get()) { render_frame()->GetServiceRegistry()->ConnectToRemoteService( @@ -82,25 +74,38 @@ bool GeolocationDispatcher::lastPosition(WebGeolocationPosition&) { // conversion is necessary. void GeolocationDispatcher::requestPermission( const WebGeolocationPermissionRequest& permissionRequest) { - int bridge_id = pending_permissions_->add(permissionRequest); - base::string16 origin = permissionRequest.securityOrigin().toString(); - Send(new GeolocationHostMsg_RequestPermission( - routing_id(), bridge_id, GURL(origin), - blink::WebUserGestureIndicator::isProcessingUserGesture())); + if (!permission_service_.get()) { + render_frame()->GetServiceRegistry()->ConnectToRemoteService( + &permission_service_); + } + + int permission_request_id = pending_permissions_->add(permissionRequest); + + PermissionName permission = PERMISSION_NAME_GEOLOCATION; + + permission_service_->RequestPermission( + permission, + permissionRequest.securityOrigin().toString().utf8(), + base::Bind(&GeolocationDispatcher::OnPermissionSet, + base::Unretained(this), + permission_request_id)); } void GeolocationDispatcher::cancelPermissionRequest( - const WebGeolocationPermissionRequest& permissionRequest) { - int bridge_id; - pending_permissions_->remove(permissionRequest, bridge_id); + const blink::WebGeolocationPermissionRequest& permissionRequest) { + int permission_request_id; + pending_permissions_->remove(permissionRequest, permission_request_id); } // Permission for using geolocation has been set. -void GeolocationDispatcher::OnPermissionSet(int bridge_id, bool is_allowed) { +void GeolocationDispatcher::OnPermissionSet( + int permission_request_id, + PermissionStatus status) { WebGeolocationPermissionRequest permissionRequest; - if (!pending_permissions_->remove(bridge_id, permissionRequest)) + if (!pending_permissions_->remove(permission_request_id, permissionRequest)) return; - permissionRequest.setIsAllowed(is_allowed); + + permissionRequest.setIsAllowed(status == PERMISSION_STATUS_GRANTED); } void GeolocationDispatcher::OnLocationUpdate(MojoGeopositionPtr geoposition) { diff --git a/content/renderer/geolocation_dispatcher.h b/content/renderer/geolocation_dispatcher.h index 454859d05258..8d48d588817e 100644 --- a/content/renderer/geolocation_dispatcher.h +++ b/content/renderer/geolocation_dispatcher.h @@ -7,6 +7,7 @@ #include "base/memory/scoped_ptr.h" #include "content/common/geolocation_service.mojom.h" +#include "content/common/permission_service.mojom.h" #include "content/public/renderer/render_frame_observer.h" #include "third_party/WebKit/public/web/WebGeolocationClient.h" #include "third_party/WebKit/public/web/WebGeolocationController.h" @@ -33,9 +34,6 @@ class GeolocationDispatcher virtual ~GeolocationDispatcher(); private: - // RenderFrame::Observer implementation. - bool OnMessageReceived(const IPC::Message& message) override; - // WebGeolocationClient virtual void startUpdating(); virtual void stopUpdating(); @@ -51,7 +49,7 @@ class GeolocationDispatcher void OnLocationUpdate(MojoGeopositionPtr geoposition) override; // Permission for using geolocation has been set. - void OnPermissionSet(int bridge_id, bool is_allowed); + void OnPermissionSet(int permission_request_id, PermissionStatus status); scoped_ptr controller_; @@ -59,6 +57,7 @@ class GeolocationDispatcher pending_permissions_; GeolocationServicePtr geolocation_service_; bool enable_high_accuracy_; + PermissionServicePtr permission_service_; }; } // namespace content -- 2.11.4.GIT