| 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();
|
| }
|
| }
|
|
|
|
|