Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(944)

Unified Diff: third_party/WebKit/Source/modules/geolocation/Geolocation.cpp

Issue 1367853002: Move GeolocationDispatcher into blink. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
diff --git a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
index 036b29e820c6a6426612f9dea719ddb00a1122c2..b669b724ea8e8076875f3a9dc7b4c748709662f9 100644
--- a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
+++ b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
@@ -32,53 +32,53 @@
#include "core/frame/OriginsUsingFeatures.h"
#include "core/frame/Settings.h"
#include "modules/geolocation/Coordinates.h"
-#include "modules/geolocation/GeolocationController.h"
#include "modules/geolocation/GeolocationError.h"
-#include "modules/geolocation/GeolocationPosition.h"
-#include "platform/weborigin/SecurityOrigin.h"
+#include "platform/mojo/MojoHelper.h"
+#include "public/platform/ServiceRegistry.h"
#include "wtf/CurrentTime.h"
namespace blink {
+namespace {
static const char permissionDeniedErrorMessage[] = "User denied Geolocation";
static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocation service";
static const char framelessDocumentErrorMessage[] = "Geolocation cannot be used in frameless documents";
-static Geoposition* createGeoposition(GeolocationPosition* position)
+static Geoposition* createGeoposition(const mojom::blink::Geoposition& position)
{
- if (!position)
- return nullptr;
-
Coordinates* coordinates = Coordinates::create(
- position->latitude(),
- position->longitude(),
- position->canProvideAltitude(),
- position->altitude(),
- position->accuracy(),
- position->canProvideAltitudeAccuracy(),
- position->altitudeAccuracy(),
- position->canProvideHeading(),
- position->heading(),
- position->canProvideSpeed(),
- position->speed());
- return Geoposition::create(coordinates, convertSecondsToDOMTimeStamp(position->timestamp()));
-}
-
-static PositionError* createPositionError(GeolocationError* error)
-{
- PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE;
- switch (error->code()) {
- case GeolocationError::PermissionDenied:
- code = PositionError::PERMISSION_DENIED;
+ position.latitude,
+ position.longitude,
+ position.altitude > -10000.,
+ position.altitude,
+ position.accuracy,
+ position.altitude_accuracy >= 0.,
+ position.altitude_accuracy,
+ position.heading >= 0. && position.heading <= 360.,
+ position.heading,
+ position.speed >= 0.,
+ position.speed);
+ return Geoposition::create(coordinates, convertSecondsToDOMTimeStamp(position.timestamp));
+}
+
+static PositionError* createPositionError(mojom::blink::Geoposition::ErrorCode mojomErrorCode, const String& error)
+{
+ PositionError::ErrorCode errorCode = PositionError::POSITION_UNAVAILABLE;
+ switch (mojomErrorCode) {
+ case mojom::blink::Geoposition::ErrorCode::PERMISSION_DENIED:
+ errorCode = PositionError::PERMISSION_DENIED;
break;
- case GeolocationError::PositionUnavailable:
- code = PositionError::POSITION_UNAVAILABLE;
+ case mojom::blink::Geoposition::ErrorCode::POSITION_UNAVAILABLE:
+ errorCode = PositionError::POSITION_UNAVAILABLE;
break;
+ default:
Michael van Ouwerkerk 2016/05/04 13:52:16 Doesn't clang fail the build when a switch fails t
Sam McNally 2016/05/05 11:50:24 Done.
+ ASSERT_NOT_REACHED();
}
-
- return PositionError::create(code, error->message());
+ return PositionError::create(errorCode, error);
}
+} // namespace
+
Geolocation* Geolocation::create(ExecutionContext* context)
{
Geolocation* geolocation = new Geolocation(context);
@@ -88,6 +88,7 @@ Geolocation* Geolocation::create(ExecutionContext* context)
Geolocation::Geolocation(ExecutionContext* context)
: ActiveDOMObject(context)
+ , PageLifecycleObserver(document()->page())
, m_geolocationPermission(PermissionUnknown)
{
}
@@ -103,8 +104,8 @@ DEFINE_TRACE(Geolocation)
visitor->trace(m_watchers);
visitor->trace(m_pendingForPermissionNotifiers);
visitor->trace(m_lastPosition);
- visitor->trace(m_requestsAwaitingCachedPosition);
ActiveDOMObject::trace(visitor);
+ PageLifecycleObserver::trace(visitor);
}
Document* Geolocation::document() const
@@ -119,25 +120,19 @@ LocalFrame* Geolocation::frame() const
void Geolocation::stop()
{
- LocalFrame* frame = this->frame();
- if (frame && m_geolocationPermission == PermissionRequested)
- GeolocationController::from(frame)->cancelPermissionRequest(this);
+ if (m_permissionService)
Michael van Ouwerkerk 2016/05/04 13:52:16 Why not also stop m_geolocationService?
Sam McNally 2016/05/05 11:50:24 stopUpdating() stops it.
+ m_permissionService.reset();
// The frame may be moving to a new page and we want to get the permissions from the new page's client.
Michael van Ouwerkerk 2016/05/04 13:52:16 Please update this comment, there is no client any
Sam McNally 2016/05/05 11:50:24 Done.
m_geolocationPermission = PermissionUnknown;
cancelAllRequests();
stopUpdating();
m_pendingForPermissionNotifiers.clear();
+ m_lastPosition = nullptr;
}
Geoposition* Geolocation::lastPosition()
Michael van Ouwerkerk 2016/05/04 13:52:16 This can be in the header now, or removed entirely
Sam McNally 2016/05/05 11:50:24 Done.
{
- LocalFrame* frame = this->frame();
- if (!frame)
- return 0;
-
- m_lastPosition = createGeoposition(GeolocationController::from(frame)->lastPosition());
-
return m_lastPosition;
}
@@ -202,7 +197,7 @@ void Geolocation::startRequest(GeoNotifier *notifier)
// the permission state can not change again in the lifetime of this page.
if (isDenied())
notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
- else if (haveSuitableCachedPosition(notifier->options()))
+ else if (isAllowed() && haveSuitableCachedPosition(notifier->options()))
Michael van Ouwerkerk 2016/05/04 13:52:16 Why add the isAllowed call? Is it for readability?
Sam McNally 2016/05/05 11:50:24 It was for readability. Removed it and added a DCH
notifier->setUseCachedPosition();
else if (!notifier->options().timeout())
notifier->startTimer();
@@ -210,10 +205,10 @@ void Geolocation::startRequest(GeoNotifier *notifier)
// if we don't yet have permission, request for permission before calling startUpdating()
m_pendingForPermissionNotifiers.add(notifier);
requestPermission();
- } else if (startUpdating(notifier))
+ } else {
+ startUpdating(notifier);
notifier->startTimer();
- else
- notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
+ }
}
void Geolocation::fatalErrorOccurred(GeoNotifier* notifier)
@@ -228,47 +223,20 @@ void Geolocation::fatalErrorOccurred(GeoNotifier* notifier)
void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier)
{
- // This is called asynchronously, so the permissions could have been denied
- // since we last checked in startRequest.
- if (isDenied()) {
- notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
- return;
- }
-
- m_requestsAwaitingCachedPosition.add(notifier);
+ DCHECK(isAllowed());
Michael van Ouwerkerk 2016/05/04 13:52:16 This DCHECK is not equivalent to the isDenied() br
Sam McNally 2016/05/05 11:50:23 This should never be reached unless permission has
- // If permissions are allowed, make the callback
- if (isAllowed()) {
- makeCachedPositionCallbacks();
- return;
- }
-
- // Request permissions, which may be synchronous or asynchronous.
- requestPermission();
-}
+ notifier->runSuccessCallback(lastPosition());
-void Geolocation::makeCachedPositionCallbacks()
-{
- // All modifications to m_requestsAwaitingCachedPosition are done
- // asynchronously, so we don't need to worry about it being modified from
- // the callbacks.
- for (GeoNotifier* notifier : m_requestsAwaitingCachedPosition) {
- notifier->runSuccessCallback(lastPosition());
-
- // If this is a one-shot request, stop it. Otherwise, if the watch still
- // exists, start the service to get updates.
- if (m_oneShots.contains(notifier))
- m_oneShots.remove(notifier);
- else if (m_watchers.contains(notifier)) {
- if (!notifier->options().timeout() || startUpdating(notifier))
- notifier->startTimer();
- else
- notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
- }
+ // If this is a one-shot request, stop it. Otherwise, if the watch still
+ // exists, start the service to get updates.
+ if (m_oneShots.contains(notifier)) {
+ m_oneShots.remove(notifier);
+ } else if (m_watchers.contains(notifier)) {
+ if (notifier->options().timeout())
+ startUpdating(notifier);
+ notifier->startTimer();
}
- m_requestsAwaitingCachedPosition.clear();
-
if (!hasListeners())
stopUpdating();
}
@@ -306,33 +274,25 @@ void Geolocation::clearWatch(int watchID)
stopUpdating();
}
-void Geolocation::setIsAllowed(bool allowed)
+void Geolocation::onGeolocationPermissionUpdated(mojom::blink::PermissionStatus status)
{
// This may be due to either a new position from the service, or a cached position.
- m_geolocationPermission = allowed ? PermissionAllowed : PermissionDenied;
+ m_geolocationPermission = status == mojom::blink::PermissionStatus::GRANTED ? PermissionAllowed : PermissionDenied;
+ m_permissionService.reset();
- // Permission request was made during the startRequest process
- if (!m_pendingForPermissionNotifiers.isEmpty()) {
- handlePendingPermissionNotifiers();
- m_pendingForPermissionNotifiers.clear();
- return;
- }
-
- if (!isAllowed()) {
- PositionError* error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
- error->setIsFatal(true);
- handleError(error);
- m_requestsAwaitingCachedPosition.clear();
- return;
+ // While we iterate through the list, we need not worry about list being modified as the permission
Michael van Ouwerkerk 2016/05/04 13:52:16 s/list/the list/
Sam McNally 2016/05/05 11:50:24 Done.
+ // is already set to Yes/No and no new listeners will be added to the pending list.
+ for (GeoNotifier* notifier : m_pendingForPermissionNotifiers) {
+ if (isAllowed()) {
+ // start all pending notification requests as permission granted.
Michael van Ouwerkerk 2016/05/04 13:52:16 nit: s/start/Start/
Sam McNally 2016/05/05 11:50:24 Done.
+ // The notifier is always ref'ed by m_oneShots or m_watchers.
+ startUpdating(notifier);
+ notifier->startTimer();
+ } else {
+ notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
+ }
}
-
- // If the service has a last position, use it to call back for all requests.
- // If any of the requests are waiting for permission for a cached position,
- // the position from the service will be at least as fresh.
- if (lastPosition())
- makeSuccessCallbacks();
- else
- makeCachedPositionCallbacks();
+ m_pendingForPermissionNotifiers.clear();
}
void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error)
@@ -455,9 +415,15 @@ void Geolocation::requestPermission()
return;
m_geolocationPermission = PermissionRequested;
+ frame->serviceRegistry()->connectToRemoteService(
+ mojo::GetProxy(&m_permissionService));
+ m_permissionService.set_connection_error_handler(sameThreadBindForMojo(&Geolocation::onPermissionConnectionError, this));
Michael van Ouwerkerk 2016/05/04 13:52:16 Under what circumstances does this get called?
Sam McNally 2016/05/05 11:50:23 Normally, this would only happen if the browser do
// Ask the embedder: it maintains the geolocation challenge policy itself.
- GeolocationController::from(frame)->requestPermission(this);
+ m_permissionService->RequestPermission(
+ mojom::blink::PermissionName::GEOLOCATION,
+ getExecutionContext()->getSecurityOrigin()->toString(),
+ sameThreadBindForMojo(&Geolocation::onGeolocationPermissionUpdated, this));
}
void Geolocation::makeSuccessCallbacks()
@@ -476,11 +442,6 @@ void Geolocation::makeSuccessCallbacks()
// further callbacks to these notifiers.
m_oneShots.clear();
- // Also clear the set of notifiers waiting for a cached position. All the
- // oneshots and watchers will receive a position now, and if they happen to
- // be lingering in that set, avoid this bug: http://crbug.com/311876 .
- m_requestsAwaitingCachedPosition.clear();
-
sendPosition(oneShotsCopy, lastPosition());
sendPosition(watchersCopy, lastPosition());
@@ -498,46 +459,81 @@ void Geolocation::positionChanged()
makeSuccessCallbacks();
}
-void Geolocation::setError(GeolocationError* error)
+void Geolocation::startUpdating(GeoNotifier* notifier)
{
- handleError(createPositionError(error));
+ // This may be called multiple times, though stopUpdating() is called only
+ // once.
+ m_updating = true;
+ if (notifier->options().enableHighAccuracy() && !m_enableHighAccuracy) {
+ m_enableHighAccuracy = true;
+ if (m_geolocationService)
+ m_geolocationService->SetHighAccuracy(true);
+ }
+ updateGeolocationServiceConnection();
}
-bool Geolocation::startUpdating(GeoNotifier* notifier)
+void Geolocation::stopUpdating()
{
- LocalFrame* frame = this->frame();
- if (!frame)
- return false;
+ m_updating = false;
+ updateGeolocationServiceConnection();
+ m_enableHighAccuracy = false;
+}
- GeolocationController::from(frame)->addObserver(this, notifier->options().enableHighAccuracy());
- return true;
+void Geolocation::updateGeolocationServiceConnection()
+{
+ if (!page() || page()->visibilityState() != PageVisibilityStateVisible || !m_updating) {
Michael van Ouwerkerk 2016/05/04 13:52:16 nit: use page()->isPageVisible()
Sam McNally 2016/05/05 11:50:24 Done.
+ m_geolocationService.reset();
+ m_queryInProgress = false;
+ return;
+ }
+ if (m_geolocationService)
+ return;
+
+ frame()->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_geolocationService));
+ m_geolocationService.set_connection_error_handler(sameThreadBindForMojo(&Geolocation::onGeolocationConnectionError, this));
+ if (m_enableHighAccuracy)
+ m_geolocationService->SetHighAccuracy(true);
+ queryNextPosition();
}
-void Geolocation::stopUpdating()
+void Geolocation::queryNextPosition()
{
- LocalFrame* frame = this->frame();
- if (!frame)
+ if (m_queryInProgress)
return;
- GeolocationController::from(frame)->removeObserver(this);
+ m_queryInProgress = true;
+ m_geolocationService->QueryNextPosition(
+ sameThreadBindForMojo(&Geolocation::onPositionUpdated, this));
}
-void Geolocation::handlePendingPermissionNotifiers()
+void Geolocation::onPositionUpdated(mojom::blink::GeopositionPtr position)
{
- // While we iterate through the list, we need not worry about list being modified as the permission
- // is already set to Yes/No and no new listeners will be added to the pending list.
- for (GeoNotifier* notifier : m_pendingForPermissionNotifiers) {
- if (isAllowed()) {
- // start all pending notification requests as permission granted.
- // The notifier is always ref'ed by m_oneShots or m_watchers.
- if (startUpdating(notifier))
- notifier->startTimer();
- else
- notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
- } else {
- notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
- }
+ m_queryInProgress = false;
+ if (position->valid) {
+ m_lastPosition = createGeoposition(*position);
+ positionChanged();
+ } else {
+ handleError(createPositionError(position->error_code, position->error_message));
}
+ if (m_geolocationService)
+ queryNextPosition();
+}
+
+void Geolocation::pageVisibilityChanged()
+{
+ updateGeolocationServiceConnection();
+}
+
+void Geolocation::onGeolocationConnectionError()
+{
+ PositionError* error = PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage);
+ error->setIsFatal(true);
+ handleError(error);
+}
+
+void Geolocation::onPermissionConnectionError()
+{
+ onGeolocationPermissionUpdated(mojom::blink::PermissionStatus::DENIED);
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698