Chromium Code Reviews| Index: content/browser/geolocation/geolocation_dispatcher_host.cc |
| =================================================================== |
| --- content/browser/geolocation/geolocation_dispatcher_host.cc (revision 272881) |
| +++ content/browser/geolocation/geolocation_dispatcher_host.cc (working copy) |
| @@ -8,6 +8,7 @@ |
| #include "base/bind.h" |
| #include "base/metrics/histogram.h" |
| +#include "content/browser/frame_host/render_frame_host_impl.h" |
| #include "content/browser/renderer_host/render_message_filter.h" |
| #include "content/browser/renderer_host/render_process_host_impl.h" |
| #include "content/browser/renderer_host/render_view_host_impl.h" |
| @@ -64,15 +65,15 @@ |
| } |
| void SendGeolocationPermissionResponse(int render_process_id, |
| - int render_view_id, |
| + int render_frame_id, |
| int bridge_id, |
| bool allowed) { |
| - RenderViewHostImpl* render_view_host = |
| - RenderViewHostImpl::FromID(render_process_id, render_view_id); |
| - if (!render_view_host) |
| + RenderFrameHost* render_frame_host = |
| + RenderFrameHost::FromID(render_process_id, render_frame_id); |
| + if (!render_frame_host) |
| return; |
| - render_view_host->Send( |
| - new GeolocationMsg_PermissionSet(render_view_id, bridge_id, allowed)); |
| + render_frame_host->Send( |
| + new GeolocationMsg_PermissionSet(render_frame_id, bridge_id, allowed)); |
| if (allowed) |
| GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices(); |
| @@ -83,9 +84,7 @@ |
| GeolocationDispatcherHost::GeolocationDispatcherHost( |
| WebContents* web_contents) |
| : WebContentsObserver(web_contents), |
| - watching_requested_(false), |
| - paused_(false), |
| - high_accuracy_(false) { |
| + paused_(false) { |
| // 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. |
| @@ -94,21 +93,28 @@ |
| GeolocationDispatcherHost::~GeolocationDispatcherHost() { |
| } |
| +void GeolocationDispatcherHost::RenderFrameDeleted( |
| + RenderFrameHost* render_frame_host) { |
| + OnStopUpdating(render_frame_host); |
| +} |
| + |
| void GeolocationDispatcherHost::RenderViewHostChanged( |
| RenderViewHost* old_host, |
| RenderViewHost* new_host) { |
| - watching_requested_ = false; |
| + updating_frames_.clear(); |
| paused_ = false; |
| geolocation_subscription_.reset(); |
| } |
| -bool GeolocationDispatcherHost::OnMessageReceived(const IPC::Message& msg) { |
| +bool GeolocationDispatcherHost::OnMessageReceived( |
| + const IPC::Message& msg, RenderFrameHost* render_frame_host) { |
| bool handled = true; |
| - IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcherHost, msg) |
| + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(GeolocationDispatcherHost, msg, |
| + render_frame_host) |
| + IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission, |
| + OnRequestPermission) |
| IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest, |
| OnCancelPermissionRequest) |
| - IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission, |
| - OnRequestPermission) |
| IPC_MESSAGE_HANDLER(GeolocationHostMsg_StartUpdating, OnStartUpdating) |
| IPC_MESSAGE_HANDLER(GeolocationHostMsg_StopUpdating, OnStopUpdating) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| @@ -121,18 +127,25 @@ |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| RecordGeopositionErrorCode(geoposition.error_code); |
| - if (!paused_) |
| - Send(new GeolocationMsg_PositionUpdated(routing_id(), geoposition)); |
| + if (paused_) |
| + return; |
| + |
| + for (std::map<RenderFrameHost*, bool>::iterator i = updating_frames_.begin(); |
| + i != updating_frames_.end(); ++i) { |
| + i->first->Send(new GeolocationMsg_PositionUpdated( |
| + i->first->GetRoutingID(), geoposition)); |
| + } |
| } |
| void GeolocationDispatcherHost::OnRequestPermission( |
| + RenderFrameHost* render_frame_host, |
| int bridge_id, |
| const GURL& requesting_frame, |
| bool user_gesture) { |
| GeolocationPermissionContext* context = |
| web_contents()->GetBrowserContext()->GetGeolocationPermissionContext(); |
| - int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); |
| - int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); |
| + int render_process_id = render_frame_host->GetProcess()->GetID(); |
| + int render_frame_id = render_frame_host->GetRoutingID(); |
| if (context) { |
| context->RequestGeolocationPermission( |
| web_contents(), |
| @@ -141,15 +154,16 @@ |
| user_gesture, |
| base::Bind(&SendGeolocationPermissionResponse, |
| render_process_id, |
| - render_view_id, |
| + render_frame_id, |
| bridge_id)); |
| } else { |
| SendGeolocationPermissionResponse( |
| - render_process_id, render_view_id, bridge_id, true); |
| + render_process_id, render_frame_id, bridge_id, true); |
| } |
| } |
| void GeolocationDispatcherHost::OnCancelPermissionRequest( |
| + RenderFrameHost* render_frame_host, |
| int bridge_id, |
| const GURL& requesting_frame) { |
| GeolocationPermissionContext* context = |
| @@ -161,6 +175,7 @@ |
| } |
| void GeolocationDispatcherHost::OnStartUpdating( |
| + RenderFrameHost* render_frame_host, |
| const GURL& requesting_frame, |
| bool enable_high_accuracy) { |
| // StartUpdating() can be invoked as a result of high-accuracy mode |
| @@ -169,13 +184,13 @@ |
| "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy", |
| enable_high_accuracy); |
| - watching_requested_ = true; |
| - high_accuracy_ = enable_high_accuracy; |
| + updating_frames_[render_frame_host] = enable_high_accuracy; |
| RefreshGeolocationOptions(); |
| } |
| -void GeolocationDispatcherHost::OnStopUpdating() { |
| - watching_requested_ = false; |
| +void GeolocationDispatcherHost::OnStopUpdating( |
| + RenderFrameHost* render_frame_host) { |
| + updating_frames_.erase(render_frame_host); |
| RefreshGeolocationOptions(); |
| } |
| @@ -188,12 +203,20 @@ |
| void GeolocationDispatcherHost::RefreshGeolocationOptions() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - if (watching_requested_ && !paused_) { |
| + if (!updating_frames_.empty() && !paused_) { |
|
bulach
2014/05/30 15:03:12
nit: while at it, it may be better to invert with
jam
2014/05/30 16:36:54
Done.
|
| + bool high_accuracy = false; |
| + for (std::map<RenderFrameHost*, bool>::iterator i = |
| + updating_frames_.begin(); i != updating_frames_.end(); ++i) { |
| + if (i->second) { |
| + high_accuracy = true; |
| + break; |
| + } |
| + } |
| geolocation_subscription_ = GeolocationProvider::GetInstance()-> |
| AddLocationUpdateCallback( |
| base::Bind(&GeolocationDispatcherHost::OnLocationUpdate, |
| base::Unretained(this)), |
| - high_accuracy_); |
| + high_accuracy); |
| } else { |
| geolocation_subscription_.reset(); |
| } |