Index: content/browser/geolocation/geolocation_dispatcher_host.cc |
=================================================================== |
--- content/browser/geolocation/geolocation_dispatcher_host.cc (revision 269778) |
+++ content/browser/geolocation/geolocation_dispatcher_host.cc (working copy) |
@@ -11,6 +11,8 @@ |
#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" |
+#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/public/browser/browser_context.h" |
#include "content/public/browser/geolocation_permission_context.h" |
#include "content/public/common/geoposition.h" |
#include "content/common/geolocation_messages.h" |
@@ -61,16 +63,10 @@ |
GEOPOSITION_ERROR_CODE_COUNT); |
} |
-void NotifyGeolocationProviderPermissionGranted() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices(); |
-} |
- |
void SendGeolocationPermissionResponse(int render_process_id, |
int render_view_id, |
int bridge_id, |
bool allowed) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
RenderViewHostImpl* render_view_host = |
RenderViewHostImpl::FromID(render_process_id, render_view_id); |
if (!render_view_host) |
@@ -78,41 +74,37 @@ |
render_view_host->Send( |
new GeolocationMsg_PermissionSet(render_view_id, bridge_id, allowed)); |
- if (allowed) { |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&NotifyGeolocationProviderPermissionGranted)); |
- } |
+ if (allowed) |
+ GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices(); |
} |
} // namespace |
GeolocationDispatcherHost::GeolocationDispatcherHost( |
- int render_process_id, |
- GeolocationPermissionContext* geolocation_permission_context) |
- : BrowserMessageFilter(GeolocationMsgStart), |
- render_process_id_(render_process_id), |
- geolocation_permission_context_(geolocation_permission_context), |
- geolocation_provider_(NULL) { |
- callback_ = base::Bind( |
- &GeolocationDispatcherHost::OnLocationUpdate, base::Unretained(this)); |
- // This is initialized by ResourceMessageFilter. Do not add any non-trivial |
- // initialization here, defer to OnRegisterBridge which is triggered whenever |
+ WebContents* web_contents) |
+ : WebContentsObserver(web_contents), |
+ watching_requested_(false), |
+ paused_(false), |
+ high_accuracy_(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. |
} |
GeolocationDispatcherHost::~GeolocationDispatcherHost() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (geolocation_provider_) |
- geolocation_provider_->RemoveLocationUpdateCallback(callback_); |
} |
-bool GeolocationDispatcherHost::OnMessageReceived( |
- const IPC::Message& msg, bool* msg_was_ok) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- *msg_was_ok = true; |
+void GeolocationDispatcherHost::RenderViewHostChanged( |
+ RenderViewHost* old_host, |
+ RenderViewHost* new_host) { |
+ watching_requested_ = false; |
+ paused_ = false; |
+ geolocation_subscription_.reset(); |
+} |
+ |
+bool GeolocationDispatcherHost::OnMessageReceived(const IPC::Message& msg) { |
bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP_EX(GeolocationDispatcherHost, msg, *msg_was_ok) |
+ IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcherHost, msg) |
IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest, |
OnCancelPermissionRequest) |
IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission, |
@@ -126,140 +118,84 @@ |
void GeolocationDispatcherHost::OnLocationUpdate( |
const Geoposition& geoposition) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
RecordGeopositionErrorCode(geoposition.error_code); |
- for (std::map<int, RendererGeolocationOptions>::iterator it = |
- geolocation_renderers_.begin(); |
- it != geolocation_renderers_.end(); ++it) { |
- if (!(it->second.is_paused)) |
- Send(new GeolocationMsg_PositionUpdated(it->first, geoposition)); |
- } |
+ if (!paused_) |
+ Send(new GeolocationMsg_PositionUpdated(routing_id(), geoposition)); |
} |
void GeolocationDispatcherHost::OnRequestPermission( |
- int render_view_id, |
int bridge_id, |
const GURL& requesting_frame, |
bool user_gesture) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" |
- << render_view_id << ":" << bridge_id; |
- if (geolocation_permission_context_.get()) { |
- geolocation_permission_context_->RequestGeolocationPermission( |
- render_process_id_, |
- render_view_id, |
+ GeolocationPermissionContext* context = |
+ web_contents()->GetBrowserContext()->GetGeolocationPermissionContext(); |
+ int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); |
+ int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); |
+ if (context) { |
+ context->RequestGeolocationPermission( |
+ web_contents(), |
bridge_id, |
requesting_frame, |
user_gesture, |
base::Bind(&SendGeolocationPermissionResponse, |
- render_process_id_, |
+ render_process_id, |
render_view_id, |
bridge_id)); |
} else { |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&SendGeolocationPermissionResponse, render_process_id_, |
- render_view_id, bridge_id, true)); |
+ SendGeolocationPermissionResponse( |
+ render_process_id, render_view_id, bridge_id, true); |
} |
} |
void GeolocationDispatcherHost::OnCancelPermissionRequest( |
- int render_view_id, |
int bridge_id, |
const GURL& requesting_frame) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" |
- << render_view_id << ":" << bridge_id; |
- if (geolocation_permission_context_.get()) { |
- geolocation_permission_context_->CancelGeolocationPermissionRequest( |
- render_process_id_, render_view_id, bridge_id, requesting_frame); |
+ GeolocationPermissionContext* context = |
+ web_contents()->GetBrowserContext()->GetGeolocationPermissionContext(); |
+ if (context) { |
+ context->CancelGeolocationPermissionRequest( |
+ web_contents(), bridge_id, requesting_frame); |
} |
} |
void GeolocationDispatcherHost::OnStartUpdating( |
- int render_view_id, |
const GURL& requesting_frame, |
bool enable_high_accuracy) { |
// StartUpdating() can be invoked as a result of high-accuracy mode |
// being enabled / disabled. No need to record the dispatcher again. |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" |
- << render_view_id; |
UMA_HISTOGRAM_BOOLEAN( |
"Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy", |
enable_high_accuracy); |
- std::map<int, RendererGeolocationOptions>::iterator it = |
- geolocation_renderers_.find(render_view_id); |
- if (it == geolocation_renderers_.end()) { |
- bool should_start_paused = false; |
- if (pending_paused_geolocation_renderers_.erase(render_view_id) == 1) { |
- should_start_paused = true; |
- } |
- RendererGeolocationOptions opts = { |
- enable_high_accuracy, |
- should_start_paused |
- }; |
- geolocation_renderers_[render_view_id] = opts; |
- } else { |
- it->second.high_accuracy = enable_high_accuracy; |
- } |
+ watching_requested_ = true; |
+ high_accuracy_ = enable_high_accuracy; |
RefreshGeolocationOptions(); |
} |
-void GeolocationDispatcherHost::OnStopUpdating(int render_view_id) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" |
- << render_view_id; |
- DCHECK_EQ(1U, geolocation_renderers_.count(render_view_id)); |
- geolocation_renderers_.erase(render_view_id); |
+void GeolocationDispatcherHost::OnStopUpdating() { |
+ watching_requested_ = false; |
RefreshGeolocationOptions(); |
} |
-void GeolocationDispatcherHost::PauseOrResume(int render_view_id, |
- bool should_pause) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- std::map<int, RendererGeolocationOptions>::iterator it = |
- geolocation_renderers_.find(render_view_id); |
- if (it == geolocation_renderers_.end()) { |
- // This renderer is not using geolocation yet, but if it does before |
- // we get a call to resume, we should start it up in the paused state. |
- if (should_pause) { |
- pending_paused_geolocation_renderers_.insert(render_view_id); |
- } else { |
- pending_paused_geolocation_renderers_.erase(render_view_id); |
- } |
- } else { |
- RendererGeolocationOptions* opts = &(it->second); |
- if (opts->is_paused != should_pause) |
- opts->is_paused = should_pause; |
- RefreshGeolocationOptions(); |
- } |
+void GeolocationDispatcherHost::PauseOrResume(bool should_pause) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ paused_ = should_pause; |
+ RefreshGeolocationOptions(); |
} |
void GeolocationDispatcherHost::RefreshGeolocationOptions() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- bool needs_updates = false; |
- bool use_high_accuracy = false; |
- std::map<int, RendererGeolocationOptions>::const_iterator i = |
- geolocation_renderers_.begin(); |
- for (; i != geolocation_renderers_.end(); ++i) { |
- needs_updates |= !(i->second.is_paused); |
- use_high_accuracy |= i->second.high_accuracy; |
- if (needs_updates && use_high_accuracy) |
- break; |
- } |
- if (needs_updates) { |
- if (!geolocation_provider_) |
- geolocation_provider_ = GeolocationProviderImpl::GetInstance(); |
- // Re-add to re-establish our options, in case they changed. |
- geolocation_provider_->AddLocationUpdateCallback( |
- callback_, use_high_accuracy); |
+ if (watching_requested_ && !paused_) { |
+ geolocation_subscription_ = GeolocationProvider::GetInstance()-> |
+ AddLocationUpdateCallback( |
+ base::Bind(&GeolocationDispatcherHost::OnLocationUpdate, |
+ base::Unretained(this)), |
+ high_accuracy_); |
} else { |
- if (geolocation_provider_) |
- geolocation_provider_->RemoveLocationUpdateCallback(callback_); |
- geolocation_provider_ = NULL; |
+ geolocation_subscription_.reset(); |
} |
} |