summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/browser/BUILD.gn1
-rw-r--r--content/browser/android/content_view_core_impl.cc7
-rw-r--r--content/browser/devtools/protocol/page_handler.cc14
-rw-r--r--content/browser/frame_host/render_frame_host_delegate.cc5
-rw-r--r--content/browser/frame_host/render_frame_host_delegate.h4
-rw-r--r--content/browser/frame_host/render_frame_host_impl.cc27
-rw-r--r--content/browser/frame_host/render_frame_host_impl.h6
-rw-r--r--content/browser/geolocation/geolocation_dispatcher_host.cc161
-rw-r--r--content/browser/geolocation/geolocation_dispatcher_host.h47
-rw-r--r--content/browser/geolocation/geolocation_service_context.cc62
-rw-r--r--content/browser/geolocation/geolocation_service_context.h58
-rw-r--r--content/browser/geolocation/geolocation_service_impl.cc155
-rw-r--r--content/browser/geolocation/geolocation_service_impl.h64
-rw-r--r--content/browser/web_contents/web_contents_impl.cc16
-rw-r--r--content/browser/web_contents/web_contents_impl.h10
-rw-r--r--content/common/BUILD.gn2
-rw-r--r--content/common/OWNERS5
-rw-r--r--content/common/geolocation_messages.h19
-rw-r--r--content/common/geolocation_service.mojom21
-rw-r--r--content/content_browser.gypi4
-rw-r--r--content/content_common_mojo_bindings.gypi6
-rw-r--r--content/public/common/BUILD.gn7
-rw-r--r--content/public/common/OWNERS5
-rw-r--r--content/public/common/mojo_geoposition.mojom58
-rw-r--r--content/renderer/BUILD.gn1
-rw-r--r--content/renderer/geolocation_dispatcher.cc72
-rw-r--r--content/renderer/geolocation_dispatcher.h15
27 files changed, 570 insertions, 282 deletions
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index cab6cb9..a37e2b6 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -96,6 +96,7 @@ source_set("browser") {
"//content/app/strings",
"//content/browser/devtools:resources",
"//content/common:mojo_bindings",
+ "//content/public/common:mojo_bindings",
"//mojo/public/cpp/bindings",
"//mojo/public/interfaces/application",
"//mojo/public/js/bindings",
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index cdc2146..d9b9879 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -23,7 +23,7 @@
#include "content/browser/android/load_url_params.h"
#include "content/browser/android/popup_touch_handle_drawable.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
-#include "content/browser/geolocation/geolocation_dispatcher_host.h"
+#include "content/browser/geolocation/geolocation_service_context.h"
#include "content/browser/media/media_web_contents_observer.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/input/motion_event_android.h"
@@ -363,7 +363,10 @@ jint ContentViewCoreImpl::GetBackgroundColor(JNIEnv* env, jobject obj) {
}
void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause) {
- web_contents_->geolocation_dispatcher_host()->PauseOrResume(should_pause);
+ if (should_pause)
+ web_contents_->GetGeolocationServiceContext()->PauseUpdates();
+ else
+ web_contents_->GetGeolocationServiceContext()->ResumeUpdates();
}
// All positions and sizes are in CSS pixels.
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 856352e..6f5f361 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -12,7 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "content/browser/devtools/protocol/color_picker.h"
#include "content/browser/devtools/protocol/usage_and_quota_query.h"
-#include "content/browser/geolocation/geolocation_dispatcher_host.h"
+#include "content/browser/geolocation/geolocation_service_context.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -237,8 +237,8 @@ Response PageHandler::SetGeolocationOverride(double* latitude,
if (!web_contents)
return Response::InternalError("No WebContents to override");
- GeolocationDispatcherHost* geolocation_host =
- web_contents->geolocation_dispatcher_host();
+ GeolocationServiceContext* geolocation_context =
+ web_contents->GetGeolocationServiceContext();
scoped_ptr<Geoposition> geoposition(new Geoposition());
if (latitude && longitude && accuracy) {
geoposition->latitude = *latitude;
@@ -251,7 +251,7 @@ Response PageHandler::SetGeolocationOverride(double* latitude,
} else {
geoposition->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
}
- geolocation_host->SetOverride(geoposition.Pass());
+ geolocation_context->SetOverride(geoposition.Pass());
return Response::OK();
}
@@ -264,9 +264,9 @@ Response PageHandler::ClearGeolocationOverride() {
if (!web_contents)
return Response::InternalError("No WebContents to override");
- GeolocationDispatcherHost* geolocation_host =
- web_contents->geolocation_dispatcher_host();
- geolocation_host->ClearOverride();
+ GeolocationServiceContext* geolocation_context =
+ web_contents->GetGeolocationServiceContext();
+ geolocation_context->ClearOverride();
return Response::OK();
}
diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
index 799b40e..a83715d 100644
--- a/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/content/browser/frame_host/render_frame_host_delegate.cc
@@ -63,6 +63,11 @@ RenderFrameHost* RenderFrameHostDelegate::GetGuestByInstanceID(
return NULL;
}
+GeolocationServiceContext*
+RenderFrameHostDelegate::GetGeolocationServiceContext() {
+ return NULL;
+}
+
#if defined(OS_WIN)
gfx::NativeViewAccessible
RenderFrameHostDelegate::GetParentNativeViewAccessible() {
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index 0d927a4..6c22d94 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -26,6 +26,7 @@ class Message;
}
namespace content {
+class GeolocationServiceContext;
class RenderFrameHost;
class WebContents;
struct AXEventNotificationDetails;
@@ -147,6 +148,9 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
virtual RenderFrameHost* GetGuestByInstanceID(
int browser_plugin_instance_id);
+ // Gets the GeolocationServiceContext associated with this delegate.
+ virtual GeolocationServiceContext* GetGeolocationServiceContext();
+
#if defined(OS_WIN)
// Returns the frame's parent's NativeViewAccessible.
virtual gfx::NativeViewAccessible GetParentNativeViewAccessible();
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index e2c9f77..9260d43 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -24,6 +24,7 @@
#include "content/browser/frame_host/render_frame_host_delegate.h"
#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/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"
@@ -210,7 +211,6 @@ RenderFrameHostImpl::RenderFrameHostImpl(RenderViewHostImpl* render_view_host,
}
SetUpMojoIfNeeded();
-
swapout_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind(
&RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr())));
}
@@ -1224,6 +1224,21 @@ void RenderFrameHostImpl::OnHidePopup() {
}
#endif
+void RenderFrameHostImpl::RegisterMojoServices() {
+ GeolocationServiceContext* geolocation_service_context =
+ delegate_ ? delegate_->GetGeolocationServiceContext() : NULL;
+ if (geolocation_service_context) {
+ // TODO(creis): Bind process ID here so that GeolocationServiceImpl
+ // can perform permissions checks once site isolation is complete.
+ // crbug.com/426384
+ GetServiceRegistry()->AddService<GeolocationService>(
+ base::Bind(&GeolocationServiceContext::CreateService,
+ base::Unretained(geolocation_service_context),
+ base::Bind(&RenderFrameHostImpl::DidUseGeolocationPermission,
+ base::Unretained(this))));
+ }
+}
+
void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) {
// Only main frames should be swapped out and retained inside a proxy host.
if (rfh_state == STATE_SWAPPED_OUT)
@@ -1449,6 +1464,7 @@ void RenderFrameHostImpl::SetUpMojoIfNeeded() {
if (!GetProcess()->GetServiceRegistry())
return;
+ RegisterMojoServices();
RenderFrameSetupPtr setup;
GetProcess()->GetServiceRegistry()->ConnectToRemoteService(&setup);
mojo::ServiceProviderPtr service_provider;
@@ -1636,4 +1652,13 @@ void RenderFrameHostImpl::CancelSuspendedNavigations() {
navigations_suspended_ = false;
}
+void RenderFrameHostImpl::DidUseGeolocationPermission() {
+ RenderFrameHost* top_frame = frame_tree_node()->frame_tree()->GetMainFrame();
+ GetContentClient()->browser()->RegisterPermissionUsage(
+ PERMISSION_GEOLOCATION,
+ delegate_->GetAsWebContents(),
+ GetLastCommittedURL().GetOrigin(),
+ top_frame->GetLastCommittedURL().GetOrigin());
+}
+
} // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index fbc2c00..8c38ba8 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -451,6 +451,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnHidePopup();
#endif
+ // Registers Mojo services that this frame host makes available.
+ void RegisterMojoServices();
+
// Updates the state of this RenderFrameHost and clears any waiting state
// that is no longer relevant.
void SetState(RenderFrameHostImplState rfh_state);
@@ -474,6 +477,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
void UpdateGuestFrameAccessibility(
const std::map<int32, int> node_to_browser_plugin_instance_id_map);
+ // Informs the content client that geolocation permissions were used.
+ void DidUseGeolocationPermission();
+
// For now, RenderFrameHosts indirectly keep RenderViewHosts alive via a
// refcount that calls Shutdown when it reaches zero. This allows each
// RenderFrameHostManager to just care about RenderFrameHosts, while ensuring
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.cc b/content/browser/geolocation/geolocation_dispatcher_host.cc
index d677ba0..9dfec90 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.cc
+++ b/content/browser/geolocation/geolocation_dispatcher_host.cc
@@ -7,64 +7,14 @@
#include <utility>
#include "base/bind.h"
-#include "base/metrics/histogram.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/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/content_browser_client.h"
-#include "content/public/common/geoposition.h"
#include "content/common/geolocation_messages.h"
namespace content {
-namespace {
-
-// Geoposition error codes for reporting in UMA.
-enum GeopositionErrorCode {
- // NOTE: Do not renumber these as that would confuse interpretation of
- // previously logged data. When making changes, also update the enum list
- // in tools/metrics/histograms/histograms.xml to keep it in sync.
-
- // There was no error.
- GEOPOSITION_ERROR_CODE_NONE = 0,
-
- // User denied use of geolocation.
- GEOPOSITION_ERROR_CODE_PERMISSION_DENIED = 1,
-
- // Geoposition could not be determined.
- GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE = 2,
-
- // Timeout.
- GEOPOSITION_ERROR_CODE_TIMEOUT = 3,
-
- // NOTE: Add entries only immediately above this line.
- GEOPOSITION_ERROR_CODE_COUNT = 4
-};
-
-void RecordGeopositionErrorCode(Geoposition::ErrorCode error_code) {
- GeopositionErrorCode code = GEOPOSITION_ERROR_CODE_NONE;
- switch (error_code) {
- case Geoposition::ERROR_CODE_NONE:
- code = GEOPOSITION_ERROR_CODE_NONE;
- break;
- case Geoposition::ERROR_CODE_PERMISSION_DENIED:
- code = GEOPOSITION_ERROR_CODE_PERMISSION_DENIED;
- break;
- case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
- code = GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE;
- break;
- case Geoposition::ERROR_CODE_TIMEOUT:
- code = GEOPOSITION_ERROR_CODE_TIMEOUT;
- break;
- }
- UMA_HISTOGRAM_ENUMERATION("Geolocation.LocationUpdate.ErrorCode",
- code,
- GEOPOSITION_ERROR_CODE_COUNT);
-}
-
-} // namespace
GeolocationDispatcherHost::PendingPermission::PendingPermission(
int render_frame_id,
@@ -83,7 +33,6 @@ GeolocationDispatcherHost::PendingPermission::~PendingPermission() {
GeolocationDispatcherHost::GeolocationDispatcherHost(
WebContents* web_contents)
: WebContentsObserver(web_contents),
- paused_(false),
weak_factory_(this) {
// This is initialized by WebContentsImpl. Do not add any non-trivial
// initialization here, defer to OnStartUpdating which is triggered whenever
@@ -93,33 +42,11 @@ GeolocationDispatcherHost::GeolocationDispatcherHost(
GeolocationDispatcherHost::~GeolocationDispatcherHost() {
}
-void GeolocationDispatcherHost::SetOverride(
- scoped_ptr<Geoposition> geoposition) {
- geoposition_override_.swap(geoposition);
- RefreshGeolocationOptions();
- OnLocationUpdate(*geoposition_override_);
-}
-
-void GeolocationDispatcherHost::ClearOverride() {
- geoposition_override_.reset();
- RefreshGeolocationOptions();
-}
-
void GeolocationDispatcherHost::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
- OnStopUpdating(render_frame_host);
-
CancelPermissionRequestsForFrame(render_frame_host);
}
-void GeolocationDispatcherHost::RenderViewHostChanged(
- RenderViewHost* old_host,
- RenderViewHost* new_host) {
- updating_frames_.clear();
- paused_ = false;
- geolocation_subscription_.reset();
-}
-
void GeolocationDispatcherHost::DidNavigateAnyFrame(
RenderFrameHost* render_frame_host,
const LoadCommittedDetails& details,
@@ -137,44 +64,11 @@ bool GeolocationDispatcherHost::OnMessageReceived(
render_frame_host)
IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission,
OnRequestPermission)
- IPC_MESSAGE_HANDLER(GeolocationHostMsg_StartUpdating, OnStartUpdating)
- IPC_MESSAGE_HANDLER(GeolocationHostMsg_StopUpdating, OnStopUpdating)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
-void GeolocationDispatcherHost::OnLocationUpdate(
- const Geoposition& geoposition) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- RecordGeopositionErrorCode(geoposition.error_code);
- if (paused_)
- return;
-
- for (std::map<RenderFrameHost*, bool>::iterator i = updating_frames_.begin();
- i != updating_frames_.end(); ++i) {
- UpdateGeoposition(i->first, geoposition);
- }
-}
-
-void GeolocationDispatcherHost::UpdateGeoposition(
- RenderFrameHost* frame,
- const Geoposition& geoposition) {
- RenderFrameHost* top_frame = frame;
- while (top_frame->GetParent()) {
- top_frame = top_frame->GetParent();
- }
- GetContentClient()->browser()->RegisterPermissionUsage(
- content::PERMISSION_GEOLOCATION,
- web_contents(),
- frame->GetLastCommittedURL().GetOrigin(),
- top_frame->GetLastCommittedURL().GetOrigin());
-
- frame->Send(new GeolocationMsg_PositionUpdated(
- frame->GetRoutingID(), geoposition));
-}
-
void GeolocationDispatcherHost::OnRequestPermission(
RenderFrameHost* render_frame_host,
int bridge_id,
@@ -200,59 +94,6 @@ void GeolocationDispatcherHost::OnRequestPermission(
bridge_id));
}
-void GeolocationDispatcherHost::OnStartUpdating(
- RenderFrameHost* render_frame_host,
- const GURL& requesting_origin,
- 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.
- UMA_HISTOGRAM_BOOLEAN(
- "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
- enable_high_accuracy);
-
- updating_frames_[render_frame_host] = enable_high_accuracy;
- RefreshGeolocationOptions();
- if (geoposition_override_.get())
- UpdateGeoposition(render_frame_host, *geoposition_override_);
-}
-
-void GeolocationDispatcherHost::OnStopUpdating(
- RenderFrameHost* render_frame_host) {
- updating_frames_.erase(render_frame_host);
- RefreshGeolocationOptions();
-}
-
-void GeolocationDispatcherHost::PauseOrResume(bool should_pause) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- paused_ = should_pause;
- RefreshGeolocationOptions();
- if (geoposition_override_.get())
- OnLocationUpdate(*geoposition_override_);
-}
-
-void GeolocationDispatcherHost::RefreshGeolocationOptions() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (updating_frames_.empty() || paused_ || geoposition_override_.get()) {
- 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);
-}
-
void GeolocationDispatcherHost::SendGeolocationPermissionResponse(
int render_process_id,
int render_frame_id,
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.h b/content/browser/geolocation/geolocation_dispatcher_host.h
index d942cff..6359de1 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.h
+++ b/content/browser/geolocation/geolocation_dispatcher_host.h
@@ -10,41 +10,29 @@
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
-#include "content/browser/geolocation/geolocation_provider_impl.h"
#include "content/public/browser/web_contents_observer.h"
class GURL;
namespace content {
-// GeolocationDispatcherHost is an observer for Geolocation messages.
-// It's the complement of GeolocationDispatcher (owned by RenderView).
+// 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;
- // Pause or resumes geolocation. Resuming when nothing is paused is a no-op.
- // If the web contents is paused while not currently using geolocation but
- // then goes on to do so before being resumed, then it will not get
- // geolocation updates until it is resumed.
- void PauseOrResume(bool should_pause);
-
- // Enables geolocation override. This method is used by DevTools to
- // trigger possible location-specific behavior in particular web contents.
- void SetOverride(scoped_ptr<Geoposition> geoposition);
-
- // Disables geolocation override.
- void ClearOverride();
-
private:
// WebContentsObserver
void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
- void RenderViewHostChanged(RenderViewHost* old_host,
- RenderViewHost* new_host) override;
void DidNavigateAnyFrame(RenderFrameHost* render_frame_host,
- const LoadCommittedDetails& details,
- const FrameNavigateParams& params) override;
+ const LoadCommittedDetails& details,
+ const FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& msg,
RenderFrameHost* render_frame_host) override;
@@ -55,17 +43,6 @@ class GeolocationDispatcherHost : public WebContentsObserver {
int bridge_id,
const GURL& requesting_origin,
bool user_gesture);
- void OnStartUpdating(RenderFrameHost* render_frame_host,
- const GURL& requesting_origin,
- bool enable_high_accuracy);
- void OnStopUpdating(RenderFrameHost* render_frame_host);
-
- // Updates the geolocation provider with the currently required update
- // options.
- void RefreshGeolocationOptions();
-
- void OnLocationUpdate(const Geoposition& position);
- void UpdateGeoposition(RenderFrameHost* frame, const Geoposition& position);
void SendGeolocationPermissionResponse(int render_process_id,
int render_frame_id,
@@ -76,11 +53,6 @@ class GeolocationDispatcherHost : public WebContentsObserver {
// browser to cancel the permission requests.
void CancelPermissionRequestsForFrame(RenderFrameHost* render_frame_host);
- // A map from the RenderFrameHosts that have requested geolocation updates to
- // the type of accuracy they requested (true = high accuracy).
- std::map<RenderFrameHost*, bool> updating_frames_;
- bool paused_;
-
struct PendingPermission {
PendingPermission(int render_frame_id,
int render_process_id,
@@ -94,9 +66,6 @@ class GeolocationDispatcherHost : public WebContentsObserver {
};
std::vector<PendingPermission> pending_permissions_;
- scoped_ptr<GeolocationProvider::Subscription> geolocation_subscription_;
- scoped_ptr<Geoposition> geoposition_override_;
-
base::WeakPtrFactory<GeolocationDispatcherHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHost);
diff --git a/content/browser/geolocation/geolocation_service_context.cc b/content/browser/geolocation/geolocation_service_context.cc
new file mode 100644
index 0000000..bf3d46c
--- /dev/null
+++ b/content/browser/geolocation/geolocation_service_context.cc
@@ -0,0 +1,62 @@
+// 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/geolocation/geolocation_service_context.h"
+
+namespace content {
+
+GeolocationServiceContext::GeolocationServiceContext() : paused_(false) {
+}
+
+GeolocationServiceContext::~GeolocationServiceContext() {
+}
+
+void GeolocationServiceContext::CreateService(
+ const base::Closure& update_callback,
+ mojo::InterfaceRequest<GeolocationService> request) {
+ GeolocationServiceImpl* service =
+ new GeolocationServiceImpl(this, update_callback);
+ if (geoposition_override_)
+ service->SetOverride(*geoposition_override_.get());
+ services_.push_back(service);
+ mojo::WeakBindToRequest(service, &request);
+ service->StartListeningForUpdates();
+}
+
+void GeolocationServiceContext::ServiceHadConnectionError(
+ GeolocationServiceImpl* service) {
+ auto it = std::find(services_.begin(), services_.end(), service);
+ DCHECK(it != services_.end());
+ services_.erase(it);
+}
+
+void GeolocationServiceContext::PauseUpdates() {
+ paused_ = true;
+ for (auto* service : services_) {
+ service->PauseUpdates();
+ }
+}
+
+void GeolocationServiceContext::ResumeUpdates() {
+ paused_ = false;
+ for (auto* service : services_) {
+ service->ResumeUpdates();
+ }
+}
+
+void GeolocationServiceContext::SetOverride(
+ scoped_ptr<Geoposition> geoposition) {
+ geoposition_override_.swap(geoposition);
+ for (auto* service : services_) {
+ service->SetOverride(*geoposition_override_.get());
+ }
+}
+
+void GeolocationServiceContext::ClearOverride() {
+ for (auto* service : services_) {
+ service->ClearOverride();
+ }
+}
+
+} // namespace content
diff --git a/content/browser/geolocation/geolocation_service_context.h b/content/browser/geolocation/geolocation_service_context.h
new file mode 100644
index 0000000..453c8b0
--- /dev/null
+++ b/content/browser/geolocation/geolocation_service_context.h
@@ -0,0 +1,58 @@
+// 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_GEOLOCATION_GEOLOCATION_SERVICE_CONTEXT_H_
+#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_CONTEXT_H_
+
+#include "base/memory/scoped_vector.h"
+#include "content/browser/geolocation/geolocation_service_impl.h"
+
+namespace content {
+
+// Provides information to a set of GeolocationServiceImpl instances that are
+// associated with a given context. Notably, allows pausing and resuming
+// geolocation on these instances.
+class GeolocationServiceContext {
+ public:
+ GeolocationServiceContext();
+ virtual ~GeolocationServiceContext();
+
+ // Creates a GeolocationServiceImpl that is weakly bound to |request|.
+ // |update_callback| will be called when services send
+ // location updates to their clients.
+ void CreateService(const base::Closure& update_callback,
+ mojo::InterfaceRequest<GeolocationService> request);
+
+ // Called when a service has a connection error. After this call, it is no
+ // longer safe to access |service|.
+ void ServiceHadConnectionError(GeolocationServiceImpl* service);
+
+ // Pauses and resumes geolocation. Resuming when nothing is paused is a
+ // no-op. If a service is added while geolocation is paused, that service
+ // will not get geolocation updates until geolocation is resumed.
+ void PauseUpdates();
+ void ResumeUpdates();
+
+ // Returns whether geolocation updates are currently paused.
+ bool paused() { return paused_; }
+
+ // Enables geolocation override. This method can be used to trigger possible
+ // location-specific behavior in a particular context.
+ void SetOverride(scoped_ptr<Geoposition> geoposition);
+
+ // Disables geolocation override.
+ void ClearOverride();
+
+ private:
+ ScopedVector<GeolocationServiceImpl> services_;
+ bool paused_;
+
+ scoped_ptr<Geoposition> geoposition_override_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeolocationServiceContext);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_CONTEXT_H_
diff --git a/content/browser/geolocation/geolocation_service_impl.cc b/content/browser/geolocation/geolocation_service_impl.cc
new file mode 100644
index 0000000..4c855f2
--- /dev/null
+++ b/content/browser/geolocation/geolocation_service_impl.cc
@@ -0,0 +1,155 @@
+// 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/geolocation/geolocation_service_impl.h"
+
+#include "base/bind.h"
+#include "base/metrics/histogram.h"
+#include "content/browser/geolocation/geolocation_service_context.h"
+#include "content/public/common/mojo_geoposition.mojom.h"
+
+namespace content {
+
+namespace {
+
+// Geoposition error codes for reporting in UMA.
+enum GeopositionErrorCode {
+ // NOTE: Do not renumber these as that would confuse interpretation of
+ // previously logged data. When making changes, also update the enum list
+ // in tools/metrics/histograms/histograms.xml to keep it in sync.
+
+ // There was no error.
+ GEOPOSITION_ERROR_CODE_NONE = 0,
+
+ // User denied use of geolocation.
+ GEOPOSITION_ERROR_CODE_PERMISSION_DENIED = 1,
+
+ // Geoposition could not be determined.
+ GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE = 2,
+
+ // Timeout.
+ GEOPOSITION_ERROR_CODE_TIMEOUT = 3,
+
+ // NOTE: Add entries only immediately above this line.
+ GEOPOSITION_ERROR_CODE_COUNT = 4
+};
+
+void RecordGeopositionErrorCode(Geoposition::ErrorCode error_code) {
+ GeopositionErrorCode code = GEOPOSITION_ERROR_CODE_NONE;
+ switch (error_code) {
+ case Geoposition::ERROR_CODE_NONE:
+ code = GEOPOSITION_ERROR_CODE_NONE;
+ break;
+ case Geoposition::ERROR_CODE_PERMISSION_DENIED:
+ code = GEOPOSITION_ERROR_CODE_PERMISSION_DENIED;
+ break;
+ case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
+ code = GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE;
+ break;
+ case Geoposition::ERROR_CODE_TIMEOUT:
+ code = GEOPOSITION_ERROR_CODE_TIMEOUT;
+ break;
+ }
+ UMA_HISTOGRAM_ENUMERATION("Geolocation.LocationUpdate.ErrorCode",
+ code,
+ GEOPOSITION_ERROR_CODE_COUNT);
+}
+
+} // namespace
+
+GeolocationServiceImpl::GeolocationServiceImpl(
+ GeolocationServiceContext* context,
+ const base::Closure& update_callback)
+ : context_(context),
+ update_callback_(update_callback),
+ high_accuracy_(false) {
+ DCHECK(context_);
+}
+
+GeolocationServiceImpl::~GeolocationServiceImpl() {
+}
+
+void GeolocationServiceImpl::PauseUpdates() {
+ geolocation_subscription_.reset();
+}
+
+void GeolocationServiceImpl::ResumeUpdates() {
+ if (position_override_.Validate()) {
+ OnLocationUpdate(position_override_);
+ return;
+ }
+
+ StartListeningForUpdates();
+}
+
+void GeolocationServiceImpl::StartListeningForUpdates() {
+ geolocation_subscription_ =
+ GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
+ base::Bind(&GeolocationServiceImpl::OnLocationUpdate,
+ base::Unretained(this)),
+ high_accuracy_);
+}
+
+void GeolocationServiceImpl::SetHighAccuracy(bool high_accuracy) {
+ UMA_HISTOGRAM_BOOLEAN(
+ "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
+ high_accuracy);
+ high_accuracy_ = high_accuracy;
+
+ if (position_override_.Validate()) {
+ OnLocationUpdate(position_override_);
+ return;
+ }
+
+ StartListeningForUpdates();
+}
+
+void GeolocationServiceImpl::SetOverride(const Geoposition& position) {
+ position_override_ = position;
+ if (!position_override_.Validate()) {
+ ResumeUpdates();
+ }
+
+ geolocation_subscription_.reset();
+
+ OnLocationUpdate(position_override_);
+}
+
+void GeolocationServiceImpl::ClearOverride() {
+ position_override_ = Geoposition();
+ StartListeningForUpdates();
+}
+
+void GeolocationServiceImpl::OnConnectionError() {
+ context_->ServiceHadConnectionError(this);
+
+ // The above call deleted this instance, so the only safe thing to do is
+ // return.
+}
+
+void GeolocationServiceImpl::OnLocationUpdate(const Geoposition& position) {
+ RecordGeopositionErrorCode(position.error_code);
+ DCHECK(context_);
+
+ if (context_->paused())
+ return;
+
+ MojoGeopositionPtr geoposition(MojoGeoposition::New());
+ geoposition->valid = position.Validate();
+ geoposition->latitude = position.latitude;
+ geoposition->longitude = position.longitude;
+ geoposition->altitude = position.altitude;
+ geoposition->accuracy = position.accuracy;
+ geoposition->altitude_accuracy = position.altitude_accuracy;
+ geoposition->heading = position.heading;
+ geoposition->speed = position.speed;
+ geoposition->timestamp = position.timestamp.ToDoubleT();
+ geoposition->error_code = MojoGeoposition::ErrorCode(position.error_code);
+ geoposition->error_message = position.error_message;
+
+ update_callback_.Run();
+ client()->OnLocationUpdate(geoposition.Pass());
+}
+
+} // namespace content
diff --git a/content/browser/geolocation/geolocation_service_impl.h b/content/browser/geolocation/geolocation_service_impl.h
new file mode 100644
index 0000000..172e4e1
--- /dev/null
+++ b/content/browser/geolocation/geolocation_service_impl.h
@@ -0,0 +1,64 @@
+// 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 "base/memory/scoped_ptr.h"
+#include "content/browser/geolocation/geolocation_provider_impl.h"
+#include "content/common/geolocation_service.mojom.h"
+
+#ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_IMPL_H_
+#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_IMPL_H_
+
+namespace content {
+
+class GeolocationProvider;
+class GeolocationServiceContext;
+
+// Implements the GeolocationService Mojo interface.
+class GeolocationServiceImpl : public mojo::InterfaceImpl<GeolocationService> {
+ public:
+ // |context| must outlive this object. |update_callback| will be
+ // called when location updates are sent.
+ GeolocationServiceImpl(GeolocationServiceContext* context,
+ const base::Closure& update_callback);
+ ~GeolocationServiceImpl() override;
+
+ // Starts listening for updates.
+ void StartListeningForUpdates();
+
+ // Pauses and resumes sending updates to the client of this instance.
+ void PauseUpdates();
+ void ResumeUpdates();
+
+ // Enables and disables geolocation override.
+ void SetOverride(const Geoposition& position);
+ void ClearOverride();
+
+ private:
+ // GeolocationService:
+ void SetHighAccuracy(bool high_accuracy) override;
+
+ // mojo::InterfaceImpl:
+ void OnConnectionError() override;
+
+ void OnLocationUpdate(const Geoposition& position);
+
+ // Owns this object.
+ GeolocationServiceContext* context_;
+ scoped_ptr<GeolocationProvider::Subscription> geolocation_subscription_;
+ base::Closure update_callback_;
+
+ // Valid iff SetOverride() has been called and ClearOverride() has not
+ // subsequently been called.
+ Geoposition position_override_;
+
+ // Whether this instance is currently observing location updates with high
+ // accuracy.
+ bool high_accuracy_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeolocationServiceImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_SERVICE_IMPL_H_
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index e6ee4cf..eb78a82 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -36,6 +36,7 @@
#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"
#include "content/browser/manifest/manifest_manager_host.h"
@@ -284,9 +285,8 @@ WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() {
// WebContentsImpl -------------------------------------------------------------
-WebContentsImpl::WebContentsImpl(
- BrowserContext* browser_context,
- WebContentsImpl* opener)
+WebContentsImpl::WebContentsImpl(BrowserContext* browser_context,
+ WebContentsImpl* opener)
: delegate_(NULL),
controller_(this, browser_context),
render_view_host_delegate_view_(NULL),
@@ -296,7 +296,10 @@ WebContentsImpl::WebContentsImpl(
accessible_parent_(NULL),
#endif
frame_tree_(new NavigatorImpl(&controller_, this),
- this, this, this, this),
+ this,
+ this,
+ this,
+ this),
is_loading_(false),
is_load_to_different_document_(false),
crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING),
@@ -327,6 +330,7 @@ WebContentsImpl::WebContentsImpl(
is_subframe_(false),
force_disable_overscroll_content_(false),
last_dialog_suppressed_(false),
+ geolocation_service_context_(new GeolocationServiceContext()),
accessibility_mode_(
BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()),
audio_stream_monitor_(this),
@@ -1805,6 +1809,10 @@ RenderFrameHost* WebContentsImpl::GetGuestByInstanceID(
return guest->GetMainFrame();
}
+GeolocationServiceContext* WebContentsImpl::GetGeolocationServiceContext() {
+ return geolocation_service_context_.get();
+}
+
void WebContentsImpl::OnShowValidationMessage(
const gfx::Rect& anchor_in_root_view,
const base::string16& main_text,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index c437796..88eaf22 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -52,6 +52,7 @@ class BrowserPluginGuestManager;
class DateTimeChooserAndroid;
class DownloadItem;
class GeolocationDispatcherHost;
+class GeolocationServiceContext;
class InterstitialPageImpl;
class JavaScriptDialogManager;
class ManifestManagerHost;
@@ -173,10 +174,6 @@ class CONTENT_EXPORT WebContentsImpl
WebContentsView* GetView() const;
- GeolocationDispatcherHost* geolocation_dispatcher_host() {
- return geolocation_dispatcher_host_.get();
- }
-
ScreenOrientationDispatcherHost* screen_orientation_dispatcher_host() {
return screen_orientation_dispatcher_host_.get();
}
@@ -385,8 +382,9 @@ class CONTENT_EXPORT WebContentsImpl
const std::vector<AXEventNotificationDetails>& details) override;
RenderFrameHost* GetGuestByInstanceID(
int browser_plugin_instance_id) override;
+ GeolocationServiceContext* GetGeolocationServiceContext() override;
#if defined(OS_WIN)
- virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() override;
+ gfx::NativeViewAccessible GetParentNativeViewAccessible() override;
#endif
// RenderViewHostDelegate ----------------------------------------------------
@@ -1194,6 +1192,8 @@ class CONTENT_EXPORT WebContentsImpl
// Whether the last JavaScript dialog shown was suppressed. Used for testing.
bool last_dialog_suppressed_;
+ scoped_ptr<GeolocationServiceContext> geolocation_service_context_;
+
scoped_ptr<GeolocationDispatcherHost> geolocation_dispatcher_host_;
scoped_ptr<MidiDispatcherHost> midi_dispatcher_host_;
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 0417e92..276b5b5 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -318,10 +318,12 @@ source_set("common") {
mojom("mojo_bindings") {
sources = [
+ "geolocation_service.mojom",
"render_frame_setup.mojom",
]
deps = [
+ "//content/public/common:mojo_bindings",
"//mojo/public/interfaces/application:application",
]
}
diff --git a/content/common/OWNERS b/content/common/OWNERS
index 88d8954..4bc5132 100644
--- a/content/common/OWNERS
+++ b/content/common/OWNERS
@@ -55,6 +55,11 @@ per-file *param_traits*.h=palmer@chromium.org
per-file *param_traits*.h=tsepez@chromium.org
per-file *param_traits*.h=wfh@chromium.org
+# Changes to Mojo interfaces require a security review to avoid
+# introducing new sandbox escapes.
+per-file *.mojom=set noparent
+per-file *.mojom=tsepez@chromium.org
+
# Accessibility
per-file accessibility_node_data.*=dmazzoni@chromium.org
per-file accessibility_node_data.*=dtseng@chromium.org
diff --git a/content/common/geolocation_messages.h b/content/common/geolocation_messages.h
index f89424c..b66a191 100644
--- a/content/common/geolocation_messages.h
+++ b/content/common/geolocation_messages.h
@@ -34,12 +34,6 @@ IPC_MESSAGE_ROUTED2(GeolocationMsg_PermissionSet,
int /* bridge_id */,
bool /* is_allowed */)
-// Sent after GeolocationHostMsg_StartUpdating iff the user has granted
-// permission and we have a position available or an error occurs (such as
-// permission denied, position unavailable, etc.)
-IPC_MESSAGE_ROUTED1(GeolocationMsg_PositionUpdated,
- content::Geoposition /* geoposition */)
-
// Messages sent from the renderer to the browser.
// The |bridge_id| representing |host| is requesting permission to access
@@ -50,16 +44,3 @@ IPC_MESSAGE_ROUTED3(GeolocationHostMsg_RequestPermission,
int /* bridge_id */,
GURL /* origin in the frame requesting geolocation */,
bool /* user_gesture */)
-
-// The render view requests the Geolocation service to start updating.
-// This is an asynchronous call, and the browser process may eventually reply
-// with the updated geoposition, or an error (access denied, location
-// unavailable, etc.)
-IPC_MESSAGE_ROUTED2(GeolocationHostMsg_StartUpdating,
- GURL /* origin in the frame requesting geolocation */,
- bool /* enable_high_accuracy */)
-
-// The render view requests Geolocation service to stop updating.
-// Note that the geolocation service may continue to fetch geolocation data
-// for other origins.
-IPC_MESSAGE_ROUTED0(GeolocationHostMsg_StopUpdating)
diff --git a/content/common/geolocation_service.mojom b/content/common/geolocation_service.mojom
new file mode 100644
index 0000000..bde7e0f
--- /dev/null
+++ b/content/common/geolocation_service.mojom
@@ -0,0 +1,21 @@
+// 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.
+
+import "content/public/common/mojo_geoposition.mojom"
+
+module content {
+
+// The Geolocation service provides updates on the device's location to its
+// client. By default, it provides updates with low accuracy, but
+// |SetHighAccuracy()| can be called to change this.
+[Client=GeolocationServiceClient]
+interface GeolocationService {
+ SetHighAccuracy(bool high_accuracy);
+};
+
+interface GeolocationServiceClient {
+ OnLocationUpdate(MojoGeoposition geoposition);
+};
+
+}
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index c9dcea9..df89b9c 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -686,6 +686,10 @@
'browser/geolocation/geolocation_dispatcher_host.h',
'browser/geolocation/geolocation_provider_impl.cc',
'browser/geolocation/geolocation_provider_impl.h',
+ 'browser/geolocation/geolocation_service_context.cc',
+ 'browser/geolocation/geolocation_service_context.h',
+ 'browser/geolocation/geolocation_service_impl.cc',
+ 'browser/geolocation/geolocation_service_impl.h',
'browser/geolocation/location_api_adapter_android.cc',
'browser/geolocation/location_api_adapter_android.h',
'browser/geolocation/location_arbitrator.h',
diff --git a/content/content_common_mojo_bindings.gypi b/content/content_common_mojo_bindings.gypi
index 15bb27d..da5c00a 100644
--- a/content/content_common_mojo_bindings.gypi
+++ b/content/content_common_mojo_bindings.gypi
@@ -13,7 +13,13 @@
'../mojo/public/mojo_public.gyp:mojo_cpp_bindings',
],
'sources': [
+ # NOTE: Sources duplicated in //content/common/BUILD.gn:mojo_bindings.
+ 'common/geolocation_service.mojom',
'common/render_frame_setup.mojom',
+
+ # NOTE: Sources duplicated in
+ # //content/public/common/BUILD.gn:mojo_bindings.
+ 'public/common/mojo_geoposition.mojom',
],
'includes': [ '../mojo/public/tools/bindings/mojom_bindings_generator.gypi' ],
'export_dependent_settings': [
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index a1244a2..c4d0036 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/config/features.gni")
import("//content/common/common.gni")
+import("//mojo/public/tools/bindings/mojom.gni")
# See //content/BUILD.gn for how this works.
group("common") {
@@ -43,3 +44,9 @@ source_set("common_sources") {
]
}
}
+
+mojom("mojo_bindings") {
+ sources = [
+ "mojo_geoposition.mojom",
+ ]
+}
diff --git a/content/public/common/OWNERS b/content/public/common/OWNERS
index 1e8a3aa..86e4104 100644
--- a/content/public/common/OWNERS
+++ b/content/public/common/OWNERS
@@ -12,3 +12,8 @@ per-file *param_traits*.h=nasko@chromium.org
per-file *param_traits*.h=palmer@chromium.org
per-file *param_traits*.h=tsepez@chromium.org
per-file *param_traits*.h=wfh@chromium.org
+
+# Changes to Mojo interfaces require a security review to avoid
+# introducing new sandbox escapes.
+per-file *.mojom=set noparent
+per-file *.mojom=tsepez@chromium.org
diff --git a/content/public/common/mojo_geoposition.mojom b/content/public/common/mojo_geoposition.mojom
new file mode 100644
index 0000000..f9818b5
--- /dev/null
+++ b/content/public/common/mojo_geoposition.mojom
@@ -0,0 +1,58 @@
+// 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.
+
+// This file declares the Geoposition structure, used to represent a position
+// fix. It was originally derived from:
+// http://gears.googlecode.com/svn/trunk/gears/geolocation/geolocation.h
+// TODO(blundell): Investigate killing content::Geoposition in favor of using
+// this struct everywhere (and renaming it to Geoposition).
+
+module content {
+
+struct MojoGeoposition {
+ // These values follow the W3C geolocation specification and can be returned
+ // to JavaScript without the need for a conversion.
+ enum ErrorCode {
+ ERROR_CODE_NONE = 0, // Chrome addition.
+ ERROR_CODE_PERMISSION_DENIED = 1,
+ ERROR_CODE_POSITION_UNAVAILABLE = 2,
+ ERROR_CODE_TIMEOUT = 3,
+ ERROR_CODE_LAST = ERROR_CODE_TIMEOUT
+ };
+
+ // Whether this geoposition is valid.
+ bool valid;
+
+ // These properties correspond to those of the JavaScript Position object
+ // although their types may differ.
+ // Latitude in decimal degrees north (WGS84 coordinate frame).
+ double latitude;
+ // Longitude in decimal degrees west (WGS84 coordinate frame).
+ double longitude;
+ // Altitude in meters (above WGS84 datum).
+ double altitude;
+ // Accuracy of horizontal position in meters.
+ double accuracy;
+ // Accuracy of altitude in meters.
+ double altitude_accuracy;
+ // Heading in decimal degrees clockwise from true north.
+ double heading;
+ // Horizontal component of device velocity in meters per second.
+ double speed;
+ // TODO(blundell): If I need to represent this differently to use this
+ // struct to replace content::Geolocation, I'll need to convert
+ // correctly into seconds-since-epoch when using this in
+ // GeolocationDispatcher::OnLocationUpdate().
+ // Time of position measurement in seconds since Epoch in UTC time. This is
+ // taken from the host computer's system clock (i.e. from Time::Now(), not the
+ // source device's clock).
+ double timestamp;
+
+ // Error code, see enum above.
+ ErrorCode error_code;
+ // Human-readable error message.
+ string error_message;
+};
+
+}
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 388570b..a9b54c2 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -31,6 +31,7 @@ source_set("renderer") {
"//content/common:mojo_bindings",
"//content/public/child:child_sources",
"//content/public/common:common_sources",
+ "//content/public/common:mojo_bindings",
"//gin",
"//gpu",
"//gpu/command_buffer/client:gles2_interface",
diff --git a/content/renderer/geolocation_dispatcher.cc b/content/renderer/geolocation_dispatcher.cc
index a099a3d9..fde4fc9 100644
--- a/content/renderer/geolocation_dispatcher.cc
+++ b/content/renderer/geolocation_dispatcher.cc
@@ -25,8 +25,7 @@ namespace content {
GeolocationDispatcher::GeolocationDispatcher(RenderFrame* render_frame)
: RenderFrameObserver(render_frame),
pending_permissions_(new WebGeolocationPermissionRequestManager()),
- enable_high_accuracy_(false),
- updating_(false) {
+ enable_high_accuracy_(false) {
}
GeolocationDispatcher::~GeolocationDispatcher() {}
@@ -35,22 +34,23 @@ bool GeolocationDispatcher::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcher, message)
IPC_MESSAGE_HANDLER(GeolocationMsg_PermissionSet, OnPermissionSet)
- IPC_MESSAGE_HANDLER(GeolocationMsg_PositionUpdated, OnPositionUpdated)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void GeolocationDispatcher::startUpdating() {
- GURL url;
- Send(new GeolocationHostMsg_StartUpdating(
- routing_id(), url, enable_high_accuracy_));
- updating_ = true;
+ if (!geolocation_service_.get()) {
+ render_frame()->GetServiceRegistry()->ConnectToRemoteService(
+ &geolocation_service_);
+ geolocation_service_.set_client(this);
+ }
+ if (enable_high_accuracy_)
+ geolocation_service_->SetHighAccuracy(true);
}
void GeolocationDispatcher::stopUpdating() {
- Send(new GeolocationHostMsg_StopUpdating(routing_id()));
- updating_ = false;
+ geolocation_service_.reset();
}
void GeolocationDispatcher::setEnableHighAccuracy(bool enable_high_accuracy) {
@@ -61,8 +61,8 @@ void GeolocationDispatcher::setEnableHighAccuracy(bool enable_high_accuracy) {
bool has_changed = enable_high_accuracy_ != enable_high_accuracy;
enable_high_accuracy_ = enable_high_accuracy;
// We have a different accuracy requirement. Request browser to update.
- if (updating_ && has_changed)
- startUpdating();
+ if (geolocation_service_.get() && has_changed)
+ geolocation_service_->SetHighAccuracy(enable_high_accuracy_);
}
void GeolocationDispatcher::setController(
@@ -103,32 +103,27 @@ void GeolocationDispatcher::OnPermissionSet(int bridge_id, bool is_allowed) {
permissionRequest.setIsAllowed(is_allowed);
}
-// We have an updated geolocation position or error code.
-void GeolocationDispatcher::OnPositionUpdated(
- const Geoposition& geoposition) {
- // It is possible for the browser process to have queued an update message
- // before receiving the stop updating message.
- if (!updating_)
- return;
-
- if (geoposition.Validate()) {
- controller_->positionChanged(
- WebGeolocationPosition(
- geoposition.timestamp.ToDoubleT(),
- geoposition.latitude, geoposition.longitude,
- geoposition.accuracy,
- // Lowest point on land is at approximately -400 meters.
- geoposition.altitude > -10000.,
- geoposition.altitude,
- geoposition.altitude_accuracy >= 0.,
- geoposition.altitude_accuracy,
- geoposition.heading >= 0. && geoposition.heading <= 360.,
- geoposition.heading,
- geoposition.speed >= 0.,
- geoposition.speed));
+void GeolocationDispatcher::OnLocationUpdate(MojoGeopositionPtr geoposition) {
+ DCHECK(geolocation_service_.get());
+
+ if (geoposition->valid) {
+ controller_->positionChanged(WebGeolocationPosition(
+ geoposition->timestamp,
+ geoposition->latitude,
+ geoposition->longitude,
+ geoposition->accuracy,
+ // Lowest point on land is at approximately -400 meters.
+ geoposition->altitude > -10000.,
+ geoposition->altitude,
+ geoposition->altitude_accuracy >= 0.,
+ geoposition->altitude_accuracy,
+ geoposition->heading >= 0. && geoposition->heading <= 360.,
+ geoposition->heading,
+ geoposition->speed >= 0.,
+ geoposition->speed));
} else {
WebGeolocationError::Error code;
- switch (geoposition.error_code) {
+ switch (geoposition->error_code) {
case Geoposition::ERROR_CODE_PERMISSION_DENIED:
code = WebGeolocationError::ErrorPermissionDenied;
break;
@@ -136,12 +131,11 @@ void GeolocationDispatcher::OnPositionUpdated(
code = WebGeolocationError::ErrorPositionUnavailable;
break;
default:
- NOTREACHED() << geoposition.error_code;
+ NOTREACHED() << geoposition->error_code;
return;
}
- controller_->errorOccurred(
- WebGeolocationError(
- code, blink::WebString::fromUTF8(geoposition.error_message)));
+ controller_->errorOccurred(WebGeolocationError(
+ code, blink::WebString::fromUTF8(geoposition->error_message)));
}
}
diff --git a/content/renderer/geolocation_dispatcher.h b/content/renderer/geolocation_dispatcher.h
index 53fa151..454859d 100644
--- a/content/renderer/geolocation_dispatcher.h
+++ b/content/renderer/geolocation_dispatcher.h
@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_GEOLOCATION_DISPATCHER_H_
#include "base/memory/scoped_ptr.h"
+#include "content/common/geolocation_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"
@@ -23,8 +24,10 @@ struct Geoposition;
// GeolocationDispatcher is a delegate for Geolocation messages used by
// WebKit.
// It's the complement of GeolocationDispatcherHost.
-class GeolocationDispatcher : public RenderFrameObserver,
- public blink::WebGeolocationClient {
+class GeolocationDispatcher
+ : public RenderFrameObserver,
+ public blink::WebGeolocationClient,
+ public mojo::InterfaceImpl<GeolocationServiceClient> {
public:
explicit GeolocationDispatcher(RenderFrame* render_frame);
virtual ~GeolocationDispatcher();
@@ -44,18 +47,18 @@ class GeolocationDispatcher : public RenderFrameObserver,
virtual void cancelPermissionRequest(
const blink::WebGeolocationPermissionRequest& permissionRequest);
+ // GeolocationServiceClient
+ void OnLocationUpdate(MojoGeopositionPtr geoposition) override;
+
// Permission for using geolocation has been set.
void OnPermissionSet(int bridge_id, bool is_allowed);
- // We have an updated geolocation position or error code.
- void OnPositionUpdated(const content::Geoposition& geoposition);
-
scoped_ptr<blink::WebGeolocationController> controller_;
scoped_ptr<blink::WebGeolocationPermissionRequestManager>
pending_permissions_;
+ GeolocationServicePtr geolocation_service_;
bool enable_high_accuracy_;
- bool updating_;
};
} // namespace content