| Index: content/browser/geolocation/geolocation_dispatcher_host.cc
|
| ===================================================================
|
| --- content/browser/geolocation/geolocation_dispatcher_host.cc (revision 274175)
|
| +++ 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,15 +203,24 @@
|
| void GeolocationDispatcherHost::RefreshGeolocationOptions() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| - if (watching_requested_ && !paused_) {
|
| - geolocation_subscription_ = GeolocationProvider::GetInstance()->
|
| - AddLocationUpdateCallback(
|
| - base::Bind(&GeolocationDispatcherHost::OnLocationUpdate,
|
| - base::Unretained(this)),
|
| - high_accuracy_);
|
| - } else {
|
| + if (updating_frames_.empty() || paused_) {
|
| geolocation_subscription_.reset();
|
| + return;
|
| }
|
| +
|
| + 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);
|
| }
|
|
|
| } // namespace content
|
|
|