diff options
Diffstat (limited to 'Source/WebCore/Modules/geolocation')
19 files changed, 2004 insertions, 0 deletions
diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp new file mode 100644 index 000000000..ae1f4fcbc --- /dev/null +++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp @@ -0,0 +1,774 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved. + * Copyright (C) 2009 Torch Mobile, Inc. + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Geolocation.h" + +#if ENABLE(GEOLOCATION) + +#include "Chrome.h" +#include "ChromeClient.h" +#include "Document.h" +#include "Frame.h" +#include "Geoposition.h" +#include "Page.h" +#include <wtf/CurrentTime.h> + +#if ENABLE(CLIENT_BASED_GEOLOCATION) +#include "Coordinates.h" +#include "GeolocationController.h" +#include "GeolocationError.h" +#include "GeolocationPosition.h" +#include "PositionError.h" +#endif + +namespace WebCore { + +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 const int firstAvailableWatchId = 1; + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +static PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position) +{ + if (!position) + return 0; + + RefPtr<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.release(), convertSecondsToDOMTimeStamp(position->timestamp())); +} + +static PassRefPtr<PositionError> createPositionError(GeolocationError* error) +{ + PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE; + switch (error->code()) { + case GeolocationError::PermissionDenied: + code = PositionError::PERMISSION_DENIED; + break; + case GeolocationError::PositionUnavailable: + code = PositionError::POSITION_UNAVAILABLE; + break; + } + + return PositionError::create(code, error->message()); +} +#endif + +Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) + : m_geolocation(geolocation) + , m_successCallback(successCallback) + , m_errorCallback(errorCallback) + , m_options(options) + , m_timer(this, &Geolocation::GeoNotifier::timerFired) + , m_useCachedPosition(false) +{ + ASSERT(m_geolocation); + ASSERT(m_successCallback); + // If no options were supplied from JS, we should have created a default set + // of options in JSGeolocationCustom.cpp. + ASSERT(m_options); +} + +void Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error) +{ + // If a fatal error has already been set, stick with it. This makes sure that + // when permission is denied, this is the error reported, as required by the + // spec. + if (m_fatalError) + return; + + m_fatalError = error; + // An existing timer may not have a zero timeout. + m_timer.stop(); + m_timer.startOneShot(0); +} + +void Geolocation::GeoNotifier::setUseCachedPosition() +{ + m_useCachedPosition = true; + m_timer.startOneShot(0); +} + +bool Geolocation::GeoNotifier::hasZeroTimeout() const +{ + return m_options->hasTimeout() && m_options->timeout() == 0; +} + +void Geolocation::GeoNotifier::runSuccessCallback(Geoposition* position) +{ + m_successCallback->handleEvent(position); +} + +void Geolocation::GeoNotifier::startTimerIfNeeded() +{ + if (m_options->hasTimeout()) + m_timer.startOneShot(m_options->timeout() / 1000.0); +} + +void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) +{ + m_timer.stop(); + + // Protect this GeoNotifier object, since it + // could be deleted by a call to clearWatch in a callback. + RefPtr<GeoNotifier> protect(this); + + // Test for fatal error first. This is required for the case where the Frame is + // disconnected and requests are cancelled. + if (m_fatalError) { + if (m_errorCallback) + m_errorCallback->handleEvent(m_fatalError.get()); + // This will cause this notifier to be deleted. + m_geolocation->fatalErrorOccurred(this); + return; + } + + if (m_useCachedPosition) { + // Clear the cached position flag in case this is a watch request, which + // will continue to run. + m_useCachedPosition = false; + m_geolocation->requestUsesCachedPosition(this); + return; + } + + if (m_errorCallback) { + RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired"); + m_errorCallback->handleEvent(error.get()); + } + m_geolocation->requestTimedOut(this); +} + +void Geolocation::Watchers::set(int id, PassRefPtr<GeoNotifier> prpNotifier) +{ + ASSERT(id > 0); + RefPtr<GeoNotifier> notifier = prpNotifier; + + m_idToNotifierMap.set(id, notifier.get()); + m_notifierToIdMap.set(notifier.release(), id); +} + +Geolocation::GeoNotifier* Geolocation::Watchers::find(int id) +{ + ASSERT(id > 0); + IdToNotifierMap::iterator iter = m_idToNotifierMap.find(id); + if (iter == m_idToNotifierMap.end()) + return 0; + return iter->second.get(); +} + +void Geolocation::Watchers::remove(int id) +{ + ASSERT(id > 0); + IdToNotifierMap::iterator iter = m_idToNotifierMap.find(id); + if (iter == m_idToNotifierMap.end()) + return; + m_notifierToIdMap.remove(iter->second); + m_idToNotifierMap.remove(iter); +} + +void Geolocation::Watchers::remove(GeoNotifier* notifier) +{ + NotifierToIdMap::iterator iter = m_notifierToIdMap.find(notifier); + if (iter == m_notifierToIdMap.end()) + return; + m_idToNotifierMap.remove(iter->second); + m_notifierToIdMap.remove(iter); +} + +bool Geolocation::Watchers::contains(GeoNotifier* notifier) const +{ + return m_notifierToIdMap.contains(notifier); +} + +void Geolocation::Watchers::clear() +{ + m_idToNotifierMap.clear(); + m_notifierToIdMap.clear(); +} + +bool Geolocation::Watchers::isEmpty() const +{ + return m_idToNotifierMap.isEmpty(); +} + +void Geolocation::Watchers::getNotifiersVector(GeoNotifierVector& copy) const +{ + copyValuesToVector(m_idToNotifierMap, copy); +} + +Geolocation::Geolocation(Frame* frame) + : DOMWindowProperty(frame) +#if !ENABLE(CLIENT_BASED_GEOLOCATION) + , m_service(GeolocationService::create(this)) +#endif + , m_allowGeolocation(Unknown) +{ + if (!m_frame) + return; + ASSERT(m_frame->document()); + m_frame->document()->setUsingGeolocation(true); +} + +Geolocation::~Geolocation() +{ + ASSERT(m_allowGeolocation != InProgress); + ASSERT(!m_frame); +} + +Page* Geolocation::page() const +{ + return m_frame ? m_frame->page() : 0; +} + +void Geolocation::reset() +{ + Page* page = this->page(); + if (page && m_allowGeolocation == InProgress) { +#if ENABLE(CLIENT_BASED_GEOLOCATION) + page->geolocationController()->cancelPermissionRequest(this); +#else + page->chrome()->client()->cancelGeolocationPermissionRequestForFrame(m_frame, this); +#endif + } + // The frame may be moving to a new page and we want to get the permissions from the new page's client. + m_allowGeolocation = Unknown; + cancelAllRequests(); + stopUpdating(); +#if USE(PREEMPT_GEOLOCATION_PERMISSION) + m_pendingForPermissionNotifiers.clear(); +#endif +} + +void Geolocation::disconnectFrame() +{ + // Once we are disconnected from the Frame, it is no longer possible to perform any operations. + reset(); + if (m_frame && m_frame->document()) + m_frame->document()->setUsingGeolocation(false); + DOMWindowProperty::disconnectFrame(); +} + +Geoposition* Geolocation::lastPosition() +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + Page* page = this->page(); + if (!page) + return 0; + + m_lastPosition = createGeoposition(page->geolocationController()->lastPosition()); +#else + m_lastPosition = m_service->lastPosition(); +#endif + + return m_lastPosition.get(); +} + +void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) +{ + if (!m_frame) + return; + + RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options); + ASSERT(notifier); + + m_oneShots.add(notifier); +} + +int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) +{ + if (!m_frame) + return 0; + + RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options); + ASSERT(notifier); + + static int nextAvailableWatchId = firstAvailableWatchId; + // In case of overflow, make sure the ID remains positive, but reuse the ID values. + if (nextAvailableWatchId < 1) + nextAvailableWatchId = 1; + m_watchers.set(nextAvailableWatchId, notifier.release()); + return nextAvailableWatchId++; +} + +PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) +{ + RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options); + + // Check whether permissions have already been denied. Note that if this is the case, + // 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->m_options.get())) + notifier->setUseCachedPosition(); + else if (notifier->hasZeroTimeout()) + notifier->startTimerIfNeeded(); +#if USE(PREEMPT_GEOLOCATION_PERMISSION) + else if (!isAllowed()) { + // if we don't yet have permission, request for permission before calling startUpdating() + m_pendingForPermissionNotifiers.add(notifier); + requestPermission(); + } +#endif + else if (startUpdating(notifier.get())) + notifier->startTimerIfNeeded(); + else + notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); + + return notifier.release(); +} + +void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier) +{ + // This request has failed fatally. Remove it from our lists. + m_oneShots.remove(notifier); + m_watchers.remove(notifier); + + if (!hasListeners()) + stopUpdating(); +} + +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); + + // If permissions are allowed, make the callback + if (isAllowed()) { + makeCachedPositionCallbacks(); + return; + } + + // Request permissions, which may be synchronous or asynchronous. + requestPermission(); +} + +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. + GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end(); + for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) { + GeoNotifier* notifier = iter->get(); + notifier->runSuccessCallback(m_cachedPosition.get()); + + // 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->hasZeroTimeout() || startUpdating(notifier)) + notifier->startTimerIfNeeded(); + else + notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); + } + } + + m_requestsAwaitingCachedPosition.clear(); + + if (!hasListeners()) + stopUpdating(); +} + +void Geolocation::requestTimedOut(GeoNotifier* notifier) +{ + // If this is a one-shot request, stop it. + m_oneShots.remove(notifier); + + if (!hasListeners()) + stopUpdating(); +} + +bool Geolocation::haveSuitableCachedPosition(PositionOptions* options) +{ + if (!m_cachedPosition) + return false; + if (!options->hasMaximumAge()) + return true; + if (!options->maximumAge()) + return false; + DOMTimeStamp currentTimeMillis = convertSecondsToDOMTimeStamp(currentTime()); + return m_cachedPosition->timestamp() > currentTimeMillis - options->maximumAge(); +} + +void Geolocation::clearWatch(int watchId) +{ + if (watchId < firstAvailableWatchId) + return; + +#if USE(PREEMPT_GEOLOCATION_PERMISSION) + if (GeoNotifier* notifier = m_watchers.find(watchId)) + m_pendingForPermissionNotifiers.remove(notifier); +#endif + m_watchers.remove(watchId); + + if (!hasListeners()) + stopUpdating(); +} + +void Geolocation::setIsAllowed(bool allowed) +{ + // Protect the Geolocation object from garbage collection during a callback. + RefPtr<Geolocation> protect(this); + + // This may be due to either a new position from the service, or a cached + // position. + m_allowGeolocation = allowed ? Yes : No; + +#if USE(PREEMPT_GEOLOCATION_PERMISSION) + // Permission request was made during the startRequest process + if (!m_pendingForPermissionNotifiers.isEmpty()) { + handlePendingPermissionNotifiers(); + m_pendingForPermissionNotifiers.clear(); + return; + } +#endif + + if (!isAllowed()) { + RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage); + error->setIsFatal(true); + handleError(error.get()); + m_requestsAwaitingCachedPosition.clear(); + return; + } + + // 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(); +} + +void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) +{ + GeoNotifierVector::const_iterator end = notifiers.end(); + for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { + RefPtr<GeoNotifier> notifier = *it; + + if (notifier->m_errorCallback) + notifier->m_errorCallback->handleEvent(error); + } +} + +void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* position) +{ + GeoNotifierVector::const_iterator end = notifiers.end(); + for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { + RefPtr<GeoNotifier> notifier = *it; + ASSERT(notifier->m_successCallback); + + notifier->m_successCallback->handleEvent(position); + } +} + +void Geolocation::stopTimer(GeoNotifierVector& notifiers) +{ + GeoNotifierVector::const_iterator end = notifiers.end(); + for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { + RefPtr<GeoNotifier> notifier = *it; + notifier->m_timer.stop(); + } +} + +void Geolocation::stopTimersForOneShots() +{ + GeoNotifierVector copy; + copyToVector(m_oneShots, copy); + + stopTimer(copy); +} + +void Geolocation::stopTimersForWatchers() +{ + GeoNotifierVector copy; + m_watchers.getNotifiersVector(copy); + + stopTimer(copy); +} + +void Geolocation::stopTimers() +{ + stopTimersForOneShots(); + stopTimersForWatchers(); +} + +void Geolocation::cancelRequests(GeoNotifierVector& notifiers) +{ + GeoNotifierVector::const_iterator end = notifiers.end(); + for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) + (*it)->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, framelessDocumentErrorMessage)); +} + +void Geolocation::cancelAllRequests() +{ + GeoNotifierVector copy; + copyToVector(m_oneShots, copy); + cancelRequests(copy); + m_watchers.getNotifiersVector(copy); + cancelRequests(copy); +} + +void Geolocation::extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached) +{ + GeoNotifierVector nonCached; + GeoNotifierVector::iterator end = notifiers.end(); + for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { + GeoNotifier* notifier = it->get(); + if (notifier->m_useCachedPosition) { + if (cached) + cached->append(notifier); + } else + nonCached.append(notifier); + } + notifiers.swap(nonCached); +} + +void Geolocation::copyToSet(const GeoNotifierVector& src, GeoNotifierSet& dest) +{ + GeoNotifierVector::const_iterator end = src.end(); + for (GeoNotifierVector::const_iterator it = src.begin(); it != end; ++it) { + GeoNotifier* notifier = it->get(); + dest.add(notifier); + } +} + +void Geolocation::handleError(PositionError* error) +{ + ASSERT(error); + + GeoNotifierVector oneShotsCopy; + copyToVector(m_oneShots, oneShotsCopy); + + GeoNotifierVector watchersCopy; + m_watchers.getNotifiersVector(watchersCopy); + + // Clear the lists before we make the callbacks, to avoid clearing notifiers + // added by calls to Geolocation methods from the callbacks, and to prevent + // further callbacks to these notifiers. + GeoNotifierVector oneShotsWithCachedPosition; + m_oneShots.clear(); + if (error->isFatal()) + m_watchers.clear(); + else { + // Don't send non-fatal errors to notifiers due to receive a cached position. + extractNotifiersWithCachedPosition(oneShotsCopy, &oneShotsWithCachedPosition); + extractNotifiersWithCachedPosition(watchersCopy, 0); + } + + sendError(oneShotsCopy, error); + sendError(watchersCopy, error); + + // hasListeners() doesn't distinguish between notifiers due to receive a + // cached position and those requiring a fresh position. Perform the check + // before restoring the notifiers below. + if (!hasListeners()) + stopUpdating(); + + // Maintain a reference to the cached notifiers until their timer fires. + copyToSet(oneShotsWithCachedPosition, m_oneShots); +} + +void Geolocation::requestPermission() +{ + if (m_allowGeolocation > Unknown) + return; + + Page* page = this->page(); + if (!page) + return; + + m_allowGeolocation = InProgress; + + // Ask the embedder: it maintains the geolocation challenge policy itself. +#if ENABLE(CLIENT_BASED_GEOLOCATION) + page->geolocationController()->requestPermission(this); +#else + page->chrome()->client()->requestGeolocationPermissionForFrame(m_frame, this); +#endif +} + +void Geolocation::positionChangedInternal() +{ + m_cachedPosition = lastPosition(); + + // Stop all currently running timers. + stopTimers(); + + if (!isAllowed()) { + // requestPermission() will ask the chrome for permission. This may be + // implemented synchronously or asynchronously. In both cases, + // makeSuccessCallbacks() will be called if permission is granted, so + // there's nothing more to do here. + requestPermission(); + return; + } + + makeSuccessCallbacks(); +} + +void Geolocation::makeSuccessCallbacks() +{ + ASSERT(lastPosition()); + ASSERT(isAllowed()); + + GeoNotifierVector oneShotsCopy; + copyToVector(m_oneShots, oneShotsCopy); + + GeoNotifierVector watchersCopy; + m_watchers.getNotifiersVector(watchersCopy); + + // Clear the lists before we make the callbacks, to avoid clearing notifiers + // added by calls to Geolocation methods from the callbacks, and to prevent + // further callbacks to these notifiers. + m_oneShots.clear(); + + sendPosition(oneShotsCopy, lastPosition()); + sendPosition(watchersCopy, lastPosition()); + + if (!hasListeners()) + stopUpdating(); +} + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +void Geolocation::positionChanged() +{ + positionChangedInternal(); +} + +void Geolocation::setError(GeolocationError* error) +{ + RefPtr<PositionError> positionError = createPositionError(error); + handleError(positionError.get()); +} + +#else + +void Geolocation::geolocationServicePositionChanged(GeolocationService* service) +{ + ASSERT_UNUSED(service, service == m_service); + ASSERT(m_service->lastPosition()); + + positionChangedInternal(); +} + +void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service) +{ + ASSERT(service->lastError()); + + // Note that we do not stop timers here. For one-shots, the request is + // cleared in handleError. For watchers, the spec requires that the timer is + // not cleared. + handleError(service->lastError()); +} + +#endif + +bool Geolocation::startUpdating(GeoNotifier* notifier) +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + Page* page = this->page(); + if (!page) + return false; + + page->geolocationController()->addObserver(this, notifier->m_options->enableHighAccuracy()); + return true; +#else + return m_service->startUpdating(notifier->m_options.get()); +#endif +} + +void Geolocation::stopUpdating() +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + Page* page = this->page(); + if (!page) + return; + + page->geolocationController()->removeObserver(this); +#else + m_service->stopUpdating(); +#endif + +} + +#if USE(PREEMPT_GEOLOCATION_PERMISSION) +void Geolocation::handlePendingPermissionNotifiers() +{ + // 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 + GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end(); + for (GeoNotifierSet::const_iterator iter = m_pendingForPermissionNotifiers.begin(); iter != end; ++iter) { + GeoNotifier* notifier = iter->get(); + + 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->startTimerIfNeeded(); + else + notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); + } else + notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); + } +} +#endif + +} // namespace WebCore + +#else + +namespace WebCore { + +void Geolocation::clearWatch(int) {} + +void Geolocation::reset() {} + +void Geolocation::disconnectFrame() {} + +Geolocation::Geolocation(Frame*) : DOMWindowProperty(0) {} + +Geolocation::~Geolocation() {} + +void Geolocation::setIsAllowed(bool) {} + +} + +#endif // ENABLE(GEOLOCATION) diff --git a/Source/WebCore/Modules/geolocation/Geolocation.h b/Source/WebCore/Modules/geolocation/Geolocation.h new file mode 100644 index 000000000..ea55cbf1f --- /dev/null +++ b/Source/WebCore/Modules/geolocation/Geolocation.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved. + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Geolocation_h +#define Geolocation_h + +#include "DOMWindowProperty.h" +#include "Geoposition.h" +#include "PositionCallback.h" +#include "PositionError.h" +#include "PositionErrorCallback.h" +#include "PositionOptions.h" +#include "Timer.h" + +#if !ENABLE(CLIENT_BASED_GEOLOCATION) +#include "GeolocationService.h" +#endif + +namespace WebCore { + +class Frame; +#if ENABLE(CLIENT_BASED_GEOLOCATION) +class GeolocationPosition; +class GeolocationError; +#endif +class Page; + +class Geolocation : public RefCounted<Geolocation>, public DOMWindowProperty +#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION) + , public GeolocationServiceClient +#endif +{ +public: + static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); } + ~Geolocation(); + + virtual void disconnectFrame() OVERRIDE; + void reset(); + + void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>); + int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>); + void clearWatch(int watchId); + + void setIsAllowed(bool); + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + void positionChanged(); + void setError(GeolocationError*); +#else + GeolocationService* getGeolocationService() const { return m_service.get(); } +#endif + +private: + Geoposition* lastPosition(); + + bool isAllowed() const { return m_allowGeolocation == Yes; } + bool isDenied() const { return m_allowGeolocation == No; } + + explicit Geolocation(Frame*); + + Page* page() const; + + class GeoNotifier : public RefCounted<GeoNotifier> { + public: + static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); } + + void setFatalError(PassRefPtr<PositionError>); + bool hasZeroTimeout() const; + void setUseCachedPosition(); + void runSuccessCallback(Geoposition*); + void startTimerIfNeeded(); + void timerFired(Timer<GeoNotifier>*); + + RefPtr<Geolocation> m_geolocation; + RefPtr<PositionCallback> m_successCallback; + RefPtr<PositionErrorCallback> m_errorCallback; + RefPtr<PositionOptions> m_options; + Timer<GeoNotifier> m_timer; + RefPtr<PositionError> m_fatalError; + bool m_useCachedPosition; + + private: + GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>); + }; + + typedef Vector<RefPtr<GeoNotifier> > GeoNotifierVector; + typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet; + + class Watchers { + public: + void set(int id, PassRefPtr<GeoNotifier>); + GeoNotifier* find(int id); + void remove(int id); + void remove(GeoNotifier*); + bool contains(GeoNotifier*) const; + void clear(); + bool isEmpty() const; + void getNotifiersVector(GeoNotifierVector&) const; + private: + typedef HashMap<int, RefPtr<GeoNotifier> > IdToNotifierMap; + typedef HashMap<RefPtr<GeoNotifier>, int> NotifierToIdMap; + IdToNotifierMap m_idToNotifierMap; + NotifierToIdMap m_notifierToIdMap; + }; + + bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); } + + void sendError(GeoNotifierVector&, PositionError*); + void sendPosition(GeoNotifierVector&, Geoposition*); + + static void extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached); + static void copyToSet(const GeoNotifierVector&, GeoNotifierSet&); + + static void stopTimer(GeoNotifierVector&); + void stopTimersForOneShots(); + void stopTimersForWatchers(); + void stopTimers(); + + void cancelRequests(GeoNotifierVector&); + void cancelAllRequests(); + + void positionChangedInternal(); + void makeSuccessCallbacks(); + void handleError(PositionError*); + + void requestPermission(); + + bool startUpdating(GeoNotifier*); + void stopUpdating(); + +#if USE(PREEMPT_GEOLOCATION_PERMISSION) + void handlePendingPermissionNotifiers(); +#endif + +#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION) + // GeolocationServiceClient + virtual void geolocationServicePositionChanged(GeolocationService*); + virtual void geolocationServiceErrorOccurred(GeolocationService*); +#endif + + PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>); + + void fatalErrorOccurred(GeoNotifier*); + void requestTimedOut(GeoNotifier*); + void requestUsesCachedPosition(GeoNotifier*); + bool haveSuitableCachedPosition(PositionOptions*); + void makeCachedPositionCallbacks(); + + GeoNotifierSet m_oneShots; + Watchers m_watchers; +#if !ENABLE(CLIENT_BASED_GEOLOCATION) + OwnPtr<GeolocationService> m_service; +#endif +#if USE(PREEMPT_GEOLOCATION_PERMISSION) + GeoNotifierSet m_pendingForPermissionNotifiers; +#endif + RefPtr<Geoposition> m_lastPosition; + + enum { + Unknown, + InProgress, + Yes, + No + } m_allowGeolocation; + +#if ENABLE(GEOLOCATION) + RefPtr<Geoposition> m_cachedPosition; +#endif + GeoNotifierSet m_requestsAwaitingCachedPosition; +}; + +} // namespace WebCore + +#endif // Geolocation_h + diff --git a/Source/WebCore/Modules/geolocation/Geolocation.idl b/Source/WebCore/Modules/geolocation/Geolocation.idl new file mode 100644 index 000000000..4f159bcb1 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/Geolocation.idl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module core { + + // http://www.w3.org/TR/geolocation-API/#geolocation_interface + interface [ + Conditional=GEOLOCATION, + JSGenerateIsReachable=ImplFrame, + OmitConstructor + ] Geolocation { + [Custom] void getCurrentPosition(in PositionCallback successCallback, + in [Optional] PositionErrorCallback errorCallback, + in [Optional] PositionOptions options); + + [Custom] long watchPosition(in PositionCallback successCallback, + in [Optional] PositionErrorCallback errorCallback, + in [Optional] PositionOptions options); + + void clearWatch(in long watchId); + }; + +} diff --git a/Source/WebCore/Modules/geolocation/GeolocationController.cpp b/Source/WebCore/Modules/geolocation/GeolocationController.cpp new file mode 100644 index 000000000..9694a99c4 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/GeolocationController.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GeolocationController.h" +#include "GeolocationPosition.h" + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +#include "GeolocationClient.h" + +namespace WebCore { + +GeolocationController::GeolocationController(Page* page, GeolocationClient* client) + : m_page(page) + , m_client(client) +{ +} + +GeolocationController::~GeolocationController() +{ + ASSERT(m_observers.isEmpty()); + + if (m_client) + m_client->geolocationDestroyed(); +} + +PassOwnPtr<GeolocationController> GeolocationController::create(Page* page, GeolocationClient* client) +{ + return adoptPtr(new GeolocationController(page, client)); +} + +void GeolocationController::addObserver(Geolocation* observer, 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); + if (enableHighAccuracy) + m_highAccuracyObservers.add(observer); + + if (m_client) { + if (enableHighAccuracy) + m_client->setEnableHighAccuracy(true); + if (wasEmpty) + m_client->startUpdating(); + } +} + +void GeolocationController::removeObserver(Geolocation* observer) +{ + if (!m_observers.contains(observer)) + return; + + m_observers.remove(observer); + m_highAccuracyObservers.remove(observer); + + if (m_client) { + if (m_observers.isEmpty()) + m_client->stopUpdating(); + else if (m_highAccuracyObservers.isEmpty()) + m_client->setEnableHighAccuracy(false); + } +} + +void GeolocationController::requestPermission(Geolocation* geolocation) +{ + if (m_client) + m_client->requestPermission(geolocation); +} + +void GeolocationController::cancelPermissionRequest(Geolocation* geolocation) +{ + if (m_client) + m_client->cancelPermissionRequest(geolocation); +} + +void GeolocationController::positionChanged(GeolocationPosition* position) +{ + m_lastPosition = position; + Vector<RefPtr<Geolocation> > observersVector; + copyToVector(m_observers, observersVector); + for (size_t i = 0; i < observersVector.size(); ++i) + observersVector[i]->positionChanged(); +} + +void GeolocationController::errorOccurred(GeolocationError* error) +{ + Vector<RefPtr<Geolocation> > observersVector; + copyToVector(m_observers, observersVector); + for (size_t i = 0; i < observersVector.size(); ++i) + observersVector[i]->setError(error); +} + +GeolocationPosition* GeolocationController::lastPosition() +{ + if (m_lastPosition.get()) + return m_lastPosition.get(); + + if (!m_client) + return 0; + + return m_client->lastPosition(); +} + +} // namespace WebCore + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) diff --git a/Source/WebCore/Modules/geolocation/GeolocationController.h b/Source/WebCore/Modules/geolocation/GeolocationController.h new file mode 100644 index 000000000..0611dc30b --- /dev/null +++ b/Source/WebCore/Modules/geolocation/GeolocationController.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GeolocationController_h +#define GeolocationController_h + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +#include "Geolocation.h" +#include <wtf/HashSet.h> +#include <wtf/Noncopyable.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class GeolocationClient; +class GeolocationError; +class GeolocationPosition; +class Page; + +class GeolocationController { + WTF_MAKE_NONCOPYABLE(GeolocationController); +public: + ~GeolocationController(); + + static PassOwnPtr<GeolocationController> create(Page*, GeolocationClient*); + + void addObserver(Geolocation*, bool enableHighAccuracy); + void removeObserver(Geolocation*); + + void requestPermission(Geolocation*); + void cancelPermissionRequest(Geolocation*); + + void positionChanged(GeolocationPosition*); + void errorOccurred(GeolocationError*); + + GeolocationPosition* lastPosition(); + + GeolocationClient* client() { return m_client; } + +private: + GeolocationController(Page*, GeolocationClient*); + + Page* m_page; + GeolocationClient* m_client; + + RefPtr<GeolocationPosition> m_lastPosition; + typedef HashSet<RefPtr<Geolocation> > ObserversSet; + // All observers; both those requesting high accuracy and those not. + ObserversSet m_observers; + ObserversSet m_highAccuracyObservers; +}; + +} // namespace WebCore + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) + +#endif // GeolocationController_h diff --git a/Source/WebCore/Modules/geolocation/GeolocationError.h b/Source/WebCore/Modules/geolocation/GeolocationError.h new file mode 100644 index 000000000..2a3bad4a9 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/GeolocationError.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GeolocationError_h +#define GeolocationError_h + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +#include "PlatformString.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class GeolocationError : public RefCounted<GeolocationError> { +public: + enum ErrorCode { + PermissionDenied, + PositionUnavailable + }; + + static PassRefPtr<GeolocationError> create(ErrorCode code, const String& message) { return adoptRef(new GeolocationError(code, message)); } + + ErrorCode code() const { return m_code; } + const String& message() const { return m_message; } + +private: + GeolocationError(ErrorCode code, const String& message) + : m_code(code) + , m_message(message) + { + } + + ErrorCode m_code; + String m_message; +}; + +} // namespace WebCore + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) + +#endif // GeolocationError_h diff --git a/Source/WebCore/Modules/geolocation/GeolocationPosition.h b/Source/WebCore/Modules/geolocation/GeolocationPosition.h new file mode 100644 index 000000000..9f25b1147 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/GeolocationPosition.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GeolocationPosition_h +#define GeolocationPosition_h + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class GeolocationPosition : public RefCounted<GeolocationPosition> { +public: + static PassRefPtr<GeolocationPosition> create(double timestamp, double latitude, double longitude, double accuracy) { return adoptRef(new GeolocationPosition(timestamp, latitude, longitude, accuracy)); } + + static PassRefPtr<GeolocationPosition> create(double timestamp, double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed) { return adoptRef(new GeolocationPosition(timestamp, latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed)); } + + double timestamp() const { return m_timestamp; } + + double latitude() const { return m_latitude; } + double longitude() const { return m_longitude; } + double accuracy() const { return m_accuracy; } + double altitude() const { return m_altitude; } + double altitudeAccuracy() const { return m_altitudeAccuracy; } + double heading() const { return m_heading; } + double speed() const { return m_speed; } + + bool canProvideAltitude() const { return m_canProvideAltitude; } + bool canProvideAltitudeAccuracy() const { return m_canProvideAltitudeAccuracy; } + bool canProvideHeading() const { return m_canProvideHeading; } + bool canProvideSpeed() const { return m_canProvideSpeed; } + +private: + GeolocationPosition(double timestamp, double latitude, double longitude, double accuracy) + : m_timestamp(timestamp) + , m_latitude(latitude) + , m_longitude(longitude) + , m_accuracy(accuracy) + , m_altitude(0) + , m_altitudeAccuracy(0) + , m_heading(0) + , m_speed(0) + , m_canProvideAltitude(false) + , m_canProvideAltitudeAccuracy(false) + , m_canProvideHeading(false) + , m_canProvideSpeed(false) + { + } + + GeolocationPosition(double timestamp, double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed) + : m_timestamp(timestamp) + , m_latitude(latitude) + , m_longitude(longitude) + , m_accuracy(accuracy) + , m_altitude(altitude) + , m_altitudeAccuracy(altitudeAccuracy) + , m_heading(heading) + , m_speed(speed) + , m_canProvideAltitude(providesAltitude) + , m_canProvideAltitudeAccuracy(providesAltitudeAccuracy) + , m_canProvideHeading(providesHeading) + , m_canProvideSpeed(providesSpeed) + { + } + + double m_timestamp; + + double m_latitude; + double m_longitude; + double m_accuracy; + double m_altitude; + double m_altitudeAccuracy; + double m_heading; + double m_speed; + + bool m_canProvideAltitude; + bool m_canProvideAltitudeAccuracy; + bool m_canProvideHeading; + bool m_canProvideSpeed; +}; + +} // namespace WebCore + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) + +#endif // GeolocationPosition_h diff --git a/Source/WebCore/Modules/geolocation/Geoposition.h b/Source/WebCore/Modules/geolocation/Geoposition.h new file mode 100644 index 000000000..5386aaaf4 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/Geoposition.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Geoposition_h +#define Geoposition_h + +#include "Coordinates.h" +#include "Event.h" +#include "PlatformString.h" +#include <wtf/RefCounted.h> + +namespace WebCore { + +class Geoposition : public RefCounted<Geoposition> { +public: + static PassRefPtr<Geoposition> create(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp) + { + return adoptRef(new Geoposition(coordinates, timestamp)); + } + + PassRefPtr<Geoposition> isolatedCopy() const + { + return Geoposition::create(m_coordinates->isolatedCopy(), m_timestamp); + } + + DOMTimeStamp timestamp() const { return m_timestamp; } + Coordinates* coords() const { return m_coordinates.get(); } + +private: + Geoposition(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp) + : m_coordinates(coordinates) + , m_timestamp(timestamp) + { + ASSERT(m_coordinates); + } + + RefPtr<Coordinates> m_coordinates; + DOMTimeStamp m_timestamp; +}; + +} // namespace WebCore + +#endif // Geoposition_h diff --git a/Source/WebCore/Modules/geolocation/Geoposition.idl b/Source/WebCore/Modules/geolocation/Geoposition.idl new file mode 100644 index 000000000..cbe728a81 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/Geoposition.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module core { + + interface [ + Conditional=GEOLOCATION, + OmitConstructor + ] Geoposition { + readonly attribute Coordinates coords; + readonly attribute DOMTimeStamp timestamp; + }; +} diff --git a/Source/WebCore/Modules/geolocation/NavigatorGeolocation.cpp b/Source/WebCore/Modules/geolocation/NavigatorGeolocation.cpp new file mode 100644 index 000000000..b8a47c1f5 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/NavigatorGeolocation.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "config.h" +#include "NavigatorGeolocation.h" + +#include "Geolocation.h" +#include "Navigator.h" + +namespace WebCore { + +NavigatorGeolocation::NavigatorGeolocation(Frame* frame) + : DOMWindowProperty(frame) +{ +} + +NavigatorGeolocation::~NavigatorGeolocation() +{ +} + +void NavigatorGeolocation::willDetachPage() +{ + // FIXME: We should ideally allow existing Geolocation activities to continue + // when the Geolocation's iframe is reparented. (Assuming we continue to + // support reparenting iframes.) + // See https://bugs.webkit.org/show_bug.cgi?id=55577 + // and https://bugs.webkit.org/show_bug.cgi?id=52877 + if (m_geolocation) + m_geolocation->reset(); +} + +NavigatorGeolocation* NavigatorGeolocation::from(Navigator* navigator) +{ + DEFINE_STATIC_LOCAL(AtomicString, name, ("NavigatorGeolocation")); + NavigatorGeolocation* supplement = static_cast<NavigatorGeolocation*>(NavigatorSupplement::from(navigator, name)); + if (!supplement) { + supplement = new NavigatorGeolocation(navigator->frame()); + provideTo(navigator, name, adoptPtr(supplement)); + } + return supplement; +} + +Geolocation* NavigatorGeolocation::geolocation(Navigator* navigator) +{ + return NavigatorGeolocation::from(navigator)->geolocation(); +} + +Geolocation* NavigatorGeolocation::geolocation() const +{ + if (!m_geolocation) + m_geolocation = Geolocation::create(frame()); + return m_geolocation.get(); +} + +} // namespace WebCore diff --git a/Source/WebCore/Modules/geolocation/NavigatorGeolocation.h b/Source/WebCore/Modules/geolocation/NavigatorGeolocation.h new file mode 100644 index 000000000..b8c92e6a3 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/NavigatorGeolocation.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef NavigatorGeolocation_h +#define NavigatorGeolocation_h + +#include "DOMWindowProperty.h" +#include "NavigatorSupplement.h" + +namespace WebCore { + +class Frame; +class Geolocation; +class Navigator; + +class NavigatorGeolocation : public NavigatorSupplement, public DOMWindowProperty { +public: + virtual ~NavigatorGeolocation(); + static NavigatorGeolocation* from(Navigator*); + + static Geolocation* geolocation(Navigator*); + Geolocation* geolocation() const; + +private: + NavigatorGeolocation(Frame*); + + virtual void willDetachPage() OVERRIDE; + + mutable RefPtr<Geolocation> m_geolocation; +}; + +} // namespace WebCore + +#endif // NavigatorGeolocation_h diff --git a/Source/WebCore/Modules/geolocation/NavigatorGeolocation.idl b/Source/WebCore/Modules/geolocation/NavigatorGeolocation.idl new file mode 100644 index 000000000..e0b8f0ed1 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/NavigatorGeolocation.idl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +module window { + + interface [ + Conditional=GEOLOCATION, + Supplemental=Navigator + ] NavigatorGeolocation { + readonly attribute [V8EnabledAtRuntime] Geolocation geolocation; + }; + +} diff --git a/Source/WebCore/Modules/geolocation/PositionCallback.h b/Source/WebCore/Modules/geolocation/PositionCallback.h new file mode 100644 index 000000000..09d7eb692 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionCallback.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PositionCallback_h +#define PositionCallback_h + +#include <wtf/RefCounted.h> + +namespace WebCore { + + class Geoposition; + + class PositionCallback : public RefCounted<PositionCallback> { + public: + virtual ~PositionCallback() { } + virtual bool handleEvent(Geoposition*) = 0; + }; + +} // namespace WebCore + +#endif // PositionCallback_h diff --git a/Source/WebCore/Modules/geolocation/PositionCallback.idl b/Source/WebCore/Modules/geolocation/PositionCallback.idl new file mode 100644 index 000000000..39cfa34eb --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionCallback.idl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module core { + interface [ + Conditional=GEOLOCATION, + Callback + ] PositionCallback { + boolean handleEvent(in Geoposition position); + }; +} diff --git a/Source/WebCore/Modules/geolocation/PositionError.h b/Source/WebCore/Modules/geolocation/PositionError.h new file mode 100644 index 000000000..146717041 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionError.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PositionError_h +#define PositionError_h + +#include "PlatformString.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class PositionError : public RefCounted<PositionError> { +public: + enum ErrorCode { + PERMISSION_DENIED = 1, + POSITION_UNAVAILABLE = 2, + TIMEOUT = 3 + }; + + static PassRefPtr<PositionError> create(ErrorCode code, const String& message) { return adoptRef(new PositionError(code, message)); } + + ErrorCode code() const { return m_code; } + const String& message() const { return m_message; } + void setIsFatal(bool isFatal) { m_isFatal = isFatal; } + bool isFatal() const { return m_isFatal; } + +private: + PositionError(ErrorCode code, const String& message) + : m_code(code) + , m_message(message) + , m_isFatal(false) + { + } + + ErrorCode m_code; + String m_message; + // Whether the error is fatal, such that no request can ever obtain a good + // position fix in the future. + bool m_isFatal; +}; + +} // namespace WebCore + +#endif // PositionError_h diff --git a/Source/WebCore/Modules/geolocation/PositionError.idl b/Source/WebCore/Modules/geolocation/PositionError.idl new file mode 100644 index 000000000..98e036f7b --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionError.idl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module core { + + interface [ + Conditional=GEOLOCATION + ] PositionError { + readonly attribute unsigned short code; + readonly attribute DOMString message; + + const unsigned short PERMISSION_DENIED = 1; + const unsigned short POSITION_UNAVAILABLE = 2; + const unsigned short TIMEOUT = 3; + }; + +} diff --git a/Source/WebCore/Modules/geolocation/PositionErrorCallback.h b/Source/WebCore/Modules/geolocation/PositionErrorCallback.h new file mode 100644 index 000000000..d152785c1 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionErrorCallback.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PositionErrorCallback_h +#define PositionErrorCallback_h + +#include <wtf/RefCounted.h> + +namespace WebCore { + + class PositionError; + + class PositionErrorCallback : public RefCounted<PositionErrorCallback> { + public: + virtual ~PositionErrorCallback() { } + virtual bool handleEvent(PositionError*) = 0; + }; + +} // namespace WebCore + +#endif // PositionErrorCallback_h diff --git a/Source/WebCore/Modules/geolocation/PositionErrorCallback.idl b/Source/WebCore/Modules/geolocation/PositionErrorCallback.idl new file mode 100644 index 000000000..a7dc932d5 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionErrorCallback.idl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module core { + interface [ + Conditional=GEOLOCATION, + Callback + ] PositionErrorCallback { + boolean handleEvent(in PositionError error); + }; +} diff --git a/Source/WebCore/Modules/geolocation/PositionOptions.h b/Source/WebCore/Modules/geolocation/PositionOptions.h new file mode 100644 index 000000000..5cb66f735 --- /dev/null +++ b/Source/WebCore/Modules/geolocation/PositionOptions.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PositionOptions_h +#define PositionOptions_h + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class PositionOptions : public RefCounted<PositionOptions> { +public: + static PassRefPtr<PositionOptions> create() { return adoptRef(new PositionOptions()); } + + bool enableHighAccuracy() const { return m_highAccuracy; } + void setEnableHighAccuracy(bool enable) { m_highAccuracy = enable; } + bool hasTimeout() const { return m_hasTimeout; } + int timeout() const + { + ASSERT(hasTimeout()); + return m_timeout; + } + void setTimeout(int timeout) + { + ASSERT(timeout >= 0); + m_hasTimeout = true; + m_timeout = timeout; + } + bool hasMaximumAge() const { return m_hasMaximumAge; } + int maximumAge() const + { + ASSERT(hasMaximumAge()); + return m_maximumAge; + } + void clearMaximumAge() { m_hasMaximumAge = false; } + void setMaximumAge(int age) + { + ASSERT(age >= 0); + m_hasMaximumAge = true; + m_maximumAge = age; + } + +private: + PositionOptions() + : m_highAccuracy(false) + , m_hasTimeout(false) + { + setMaximumAge(0); + } + + bool m_highAccuracy; + bool m_hasTimeout; + int m_timeout; + bool m_hasMaximumAge; + int m_maximumAge; +}; + +} // namespace WebCore + +#endif // PositionOptions_h |