Index: third_party/WebKit/Source/modules/geolocation/GeolocationController.cpp |
diff --git a/third_party/WebKit/Source/modules/geolocation/GeolocationController.cpp b/third_party/WebKit/Source/modules/geolocation/GeolocationController.cpp |
index fcee1aee89b1cf10a5278b5fd13672b5663ddcfd..88bf1e02843745652174dd282911d5418fc619a5 100644 |
--- a/third_party/WebKit/Source/modules/geolocation/GeolocationController.cpp |
+++ b/third_party/WebKit/Source/modules/geolocation/GeolocationController.cpp |
@@ -27,102 +27,142 @@ |
#include "modules/geolocation/GeolocationController.h" |
+#include "components/geolocation/public/interfaces/geoposition.mojom.h" |
+#include "core/dom/Document.h" |
#include "core/page/Page.h" |
-#include "modules/geolocation/GeolocationClient.h" |
#include "modules/geolocation/GeolocationError.h" |
#include "modules/geolocation/GeolocationPosition.h" |
+#include "mojo/application/public/cpp/connect.h" |
+#include "mojo/application/public/interfaces/service_provider.mojom.h" |
+#include "platform/UserGestureIndicator.h" |
namespace blink { |
-GeolocationController::GeolocationController(LocalFrame& frame, GeolocationClient* client) |
- : PageLifecycleObserver(frame.page()) |
- , m_client(client) |
- , m_hasClientForTest(false) |
- , m_isClientUpdating(false) |
-{ |
- if (!frame.isMainFrame() && frame.page()->mainFrame()->isLocalFrame()) { |
- // internals.setGeolocationClientMock is per page. |
- GeolocationController* mainController = GeolocationController::from(frame.page()->deprecatedLocalMainFrame()); |
- if (mainController->hasClientForTest()) |
- setClientForTest(mainController->client()); |
- } |
+GeolocationController::GeolocationController(Geolocation* geolocation) |
+ : PageLifecycleObserver(geolocation->document()->page()) |
+ , m_geolocation(geolocation) |
+{ |
} |
void GeolocationController::startUpdatingIfNeeded() |
{ |
- if (m_isClientUpdating) |
+ if (m_geolocationService || !serviceProvider()) |
return; |
- m_isClientUpdating = true; |
- m_client->startUpdating(); |
+ mojo::ConnectToService(serviceProvider(), &m_geolocationService); |
+ if (m_enableHighAccuracy) |
+ m_geolocationService->SetHighAccuracy(true); |
+ QueryNextPosition(); |
} |
void GeolocationController::stopUpdatingIfNeeded() |
{ |
- if (!m_isClientUpdating) |
- return; |
- m_isClientUpdating = false; |
- m_client->stopUpdating(); |
+ m_geolocationService.reset(); |
} |
-GeolocationController::~GeolocationController() |
+void GeolocationController::setEnableHighAccuracy(bool enableHighAccuracy) |
{ |
- ASSERT(m_observers.isEmpty()); |
-#if !ENABLE(OILPAN) |
- if (m_hasClientForTest) { |
- m_client->controllerForTestRemoved(this); |
- m_hasClientForTest = false; |
+ if (m_geolocationService && enableHighAccuracy != m_enableHighAccuracy) { |
+ m_geolocationService->SetHighAccuracy(enableHighAccuracy); |
+ } |
+ m_enableHighAccuracy = enableHighAccuracy; |
+} |
+ |
+void GeolocationController::QueryNextPosition() |
+{ |
+ m_geolocationService->QueryNextPosition( |
+ [this](geolocation::GeopositionPtr geoposition) |
+ { |
+ onQueryNextPositionDone(geoposition.Pass()); |
+ }); |
+} |
+ |
+void GeolocationController::onQueryNextPositionDone(geolocation::GeopositionPtr geoposition) |
+{ |
+ auto geolocationService = m_geolocationService.get(); |
+ if (geoposition->valid) { |
+ positionChanged(GeolocationPosition::create( |
+ 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 { |
+ GeolocationError::ErrorCode code; |
+ switch (geoposition->error_code) { |
+ case geolocation::Geoposition::ERROR_CODE_NONE: |
+ return; |
+ case geolocation::Geoposition::ERROR_CODE_PERMISSION_DENIED: |
+ code = GeolocationError::PermissionDenied; |
+ break; |
+ case geolocation::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE: |
+ code = GeolocationError::PositionUnavailable; |
+ break; |
+ case geolocation::Geoposition::ERROR_CODE_TIMEOUT: |
+ return; |
+ } |
+ errorOccurred(GeolocationError::create( |
+ code, String::fromUTF8(geoposition->error_message.data(), geoposition->error_message.size()))); |
} |
-#endif |
+ if (m_geolocationService && m_geolocationService.get() == geolocationService) |
+ QueryNextPosition(); |
} |
-PassOwnPtrWillBeRawPtr<GeolocationController> GeolocationController::create(LocalFrame& frame, GeolocationClient* client) |
-{ |
- return adoptPtrWillBeNoop(new GeolocationController(frame, client)); |
-} |
+GeolocationController::~GeolocationController() = default; |
-void GeolocationController::addObserver(Geolocation* observer, bool enableHighAccuracy) |
+void GeolocationController::startUpdating(bool enableHighAccuracy) |
{ |
- // This may be called multiple times with the same observer, though removeObserver() |
- // is called only once with each. |
- bool wasEmpty = m_observers.isEmpty(); |
- m_observers.add(observer); |
+ // This may be called multiple times, though stopUpdating() is called only |
+ // once. |
+ m_updating = true; |
if (enableHighAccuracy) |
- m_highAccuracyObservers.add(observer); |
- |
- if (m_client) { |
- if (enableHighAccuracy) |
- m_client->setEnableHighAccuracy(true); |
- if (wasEmpty && page() && page()->visibilityState() == PageVisibilityStateVisible) |
- startUpdatingIfNeeded(); |
- } |
+ setEnableHighAccuracy(true); |
+ if (page() && page()->visibilityState() == PageVisibilityStateVisible) |
+ startUpdatingIfNeeded(); |
} |
-void GeolocationController::removeObserver(Geolocation* observer) |
+void GeolocationController::stopUpdating() |
{ |
- if (!m_observers.contains(observer)) |
- return; |
- |
- m_observers.remove(observer); |
- m_highAccuracyObservers.remove(observer); |
+ m_updating = false; |
+ stopUpdatingIfNeeded(); |
+ m_enableHighAccuracy = false; |
+} |
- if (m_client) { |
- if (m_observers.isEmpty()) |
- stopUpdatingIfNeeded(); |
- else if (m_highAccuracyObservers.isEmpty()) |
- m_client->setEnableHighAccuracy(false); |
+void GeolocationController::requestPermission() |
+{ |
+ if (!m_permissionService) { |
+ if (!serviceProvider()) { |
+ m_geolocation->setIsAllowed(false); |
+ return; |
+ } |
+ mojo::ConnectToService(serviceProvider(), &m_permissionService); |
} |
+ m_permissionService->RequestPermission(permission::NAME_GEOLOCATION, |
+ // FIXME: Add a type converter for WTF::String. |
+ m_geolocation->executionContext()->securityOrigin()->toString().utf8().data(), |
+ UserGestureIndicator::processingUserGesture(), |
+ [this](permission::Status status) |
+ { |
+ onRequestPermissionDone(status); |
+ }); |
} |
-void GeolocationController::requestPermission(Geolocation* geolocation) |
+void GeolocationController::cancelPermissionRequest() |
{ |
- if (m_client) |
- m_client->requestPermission(geolocation); |
+ m_permissionService.reset(); |
} |
-void GeolocationController::cancelPermissionRequest(Geolocation* geolocation) |
+void GeolocationController::onRequestPermissionDone(permission::Status status) |
{ |
- if (m_client) |
- m_client->cancelPermissionRequest(geolocation); |
+ m_geolocation->setIsAllowed(status == permission::STATUS_GRANTED); |
+ m_permissionService.reset(); |
} |
void GeolocationController::positionChanged(GeolocationPosition* position) |
@@ -132,18 +172,12 @@ void GeolocationController::positionChanged(GeolocationPosition* position) |
return; |
} |
m_lastPosition = position; |
- HeapVector<Member<Geolocation>> observersVector; |
- copyToVector(m_observers, observersVector); |
- for (size_t i = 0; i < observersVector.size(); ++i) |
- observersVector[i]->positionChanged(); |
+ m_geolocation->positionChanged(); |
} |
void GeolocationController::errorOccurred(GeolocationError* error) |
{ |
- HeapVector<Member<Geolocation>> observersVector; |
- copyToVector(m_observers, observersVector); |
- for (size_t i = 0; i < observersVector.size(); ++i) |
- observersVector[i]->setError(error); |
+ m_geolocation->setError(error); |
} |
GeolocationPosition* GeolocationController::lastPosition() |
@@ -151,51 +185,26 @@ GeolocationPosition* GeolocationController::lastPosition() |
if (m_lastPosition.get()) |
return m_lastPosition.get(); |
- if (!m_client) |
- return 0; |
- |
- return m_client->lastPosition(); |
-} |
- |
-void GeolocationController::setClientForTest(GeolocationClient* client) |
-{ |
- if (m_hasClientForTest) |
- m_client->controllerForTestRemoved(this); |
- m_client = client; |
- m_hasClientForTest = true; |
- |
- client->controllerForTestAdded(this); |
+ return nullptr; |
} |
void GeolocationController::pageVisibilityChanged() |
{ |
- if (m_observers.isEmpty() || !m_client) |
- return; |
- |
- if (page() && page()->visibilityState() == PageVisibilityStateVisible) |
+ if (page() && page()->visibilityState() == PageVisibilityStateVisible && m_updating) |
startUpdatingIfNeeded(); |
else |
stopUpdatingIfNeeded(); |
} |
-const char* GeolocationController::supplementName() |
+mojo::ServiceProvider* GeolocationController::serviceProvider() const |
{ |
- return "GeolocationController"; |
+ return m_geolocation->executionContext()->serviceProvider(); |
} |
DEFINE_TRACE(GeolocationController) |
{ |
- visitor->trace(m_client); |
visitor->trace(m_lastPosition); |
- visitor->trace(m_observers); |
- visitor->trace(m_highAccuracyObservers); |
- WillBeHeapSupplement<LocalFrame>::trace(visitor); |
PageLifecycleObserver::trace(visitor); |
} |
-void provideGeolocationTo(LocalFrame& frame, GeolocationClient* client) |
-{ |
- WillBeHeapSupplement<LocalFrame>::provideTo(frame, GeolocationController::supplementName(), GeolocationController::create(frame, client)); |
-} |
- |
} // namespace blink |