15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Torch Mobile, Inc. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright 2010, The Android Open Source Project 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/Geolocation.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Frame.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Page.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/Geoposition.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/CurrentTime.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/Coordinates.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/GeolocationController.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/GeolocationError.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/GeolocationPosition.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/geolocation/PositionError.h" 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char permissionDeniedErrorMessage[] = "User denied Geolocation"; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocation service"; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char framelessDocumentErrorMessage[] = "Geolocation cannot be used in frameless documents"; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!position) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 5302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch RefPtr<Coordinates> coordinates = Coordinates::create(position->latitude(), position->longitude(), position->canProvideAltitude(), position->altitude(), 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) position->accuracy(), position->canProvideAltitudeAccuracy(), position->altitudeAccuracy(), 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) position->canProvideHeading(), position->heading(), position->canProvideSpeed(), position->speed()); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Geoposition::create(coordinates.release(), convertSecondsToDOMTimeStamp(position->timestamp())); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PassRefPtr<PositionError> createPositionError(GeolocationError* error) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (error->code()) { 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GeolocationError::PermissionDenied: 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) code = PositionError::PERMISSION_DENIED; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GeolocationError::PositionUnavailable: 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) code = PositionError::POSITION_UNAVAILABLE; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return PositionError::create(code, error->message()); 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_geolocation(geolocation) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_successCallback(successCallback) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_errorCallback(errorCallback) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_options(options) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_timer(this, &Geolocation::GeoNotifier::timerFired) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_useCachedPosition(false) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_geolocation); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_successCallback); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If no options were supplied from JS, we should have created a default set 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of options in JSGeolocationCustom.cpp. 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_options); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If a fatal error has already been set, stick with it. This makes sure that 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // when permission is denied, this is the error reported, as required by the 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // spec. 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_fatalError) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_fatalError = error; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // An existing timer may not have a zero timeout. 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.startOneShot(0); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::setUseCachedPosition() 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_useCachedPosition = true; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.startOneShot(0); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Geolocation::GeoNotifier::hasZeroTimeout() const 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_options->hasTimeout() && m_options->timeout() == 0; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::runSuccessCallback(Geoposition* position) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we are here and the Geolocation permission is not approved, something has 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // gone horribly wrong. 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_geolocation->isAllowed()) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CRASH(); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_successCallback->handleEvent(position); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::runErrorCallback(PositionError* error) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_errorCallback) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_errorCallback->handleEvent(error); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::startTimerIfNeeded() 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_options->hasTimeout()) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.startOneShot(m_options->timeout() / 1000.0); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::stopTimer() 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Protect this GeoNotifier object, since it 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // could be deleted by a call to clearWatch in a callback. 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<GeoNotifier> protect(this); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Test for fatal error first. This is required for the case where the Frame is 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // disconnected and requests are cancelled. 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_fatalError) { 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) runErrorCallback(m_fatalError.get()); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This will cause this notifier to be deleted. 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_geolocation->fatalErrorOccurred(this); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_useCachedPosition) { 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Clear the cached position flag in case this is a watch request, which 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // will continue to run. 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_useCachedPosition = false; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_geolocation->requestUsesCachedPosition(this); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_errorCallback) { 168d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired"); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_errorCallback->handleEvent(error.get()); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_geolocation->requestTimedOut(this); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool Geolocation::Watchers::add(int id, PassRefPtr<GeoNotifier> prpNotifier) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(id > 0); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<GeoNotifier> notifier = prpNotifier; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_idToNotifierMap.add(id, notifier.get()).isNewEntry) 180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_notifierToIdMap.set(notifier.release(), id); 182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Geolocation::GeoNotifier* Geolocation::Watchers::find(int id) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(id > 0); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IdToNotifierMap::iterator iter = m_idToNotifierMap.find(id); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (iter == m_idToNotifierMap.end()) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return iter->value.get(); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::Watchers::remove(int id) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(id > 0); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IdToNotifierMap::iterator iter = m_idToNotifierMap.find(id); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (iter == m_idToNotifierMap.end()) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_notifierToIdMap.remove(iter->value); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_idToNotifierMap.remove(iter); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::Watchers::remove(GeoNotifier* notifier) 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NotifierToIdMap::iterator iter = m_notifierToIdMap.find(notifier); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (iter == m_notifierToIdMap.end()) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_idToNotifierMap.remove(iter->value); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_notifierToIdMap.remove(iter); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Geolocation::Watchers::contains(GeoNotifier* notifier) const 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_notifierToIdMap.contains(notifier); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::Watchers::clear() 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_idToNotifierMap.clear(); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_notifierToIdMap.clear(); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Geolocation::Watchers::isEmpty() const 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_idToNotifierMap.isEmpty(); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::Watchers::getNotifiersVector(GeoNotifierVector& copy) const 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) copyValuesToVector(m_idToNotifierMap, copy); 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<Geolocation> Geolocation::create(ScriptExecutionContext* context) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<Geolocation> geolocation = adoptRef(new Geolocation(context)); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) geolocation->suspendIfNeeded(); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return geolocation.release(); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Geolocation::Geolocation(ScriptExecutionContext* context) 242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : ActiveDOMObject(context) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_allowGeolocation(Unknown) 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 24553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ScriptWrappable::init(this); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Geolocation::~Geolocation() 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_allowGeolocation != InProgress); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Document* Geolocation::document() const 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return toDocument(scriptExecutionContext()); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Frame* Geolocation::frame() const 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return document() ? document()->frame() : 0; 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Page* Geolocation::page() const 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return document() ? document()->page() : 0; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::stop() 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Page* page = this->page(); 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (page && m_allowGeolocation == InProgress) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeolocationController::from(page)->cancelPermissionRequest(this); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The frame may be moving to a new page and we want to get the permissions from the new page's client. 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_allowGeolocation = Unknown; 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cancelAllRequests(); 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_pendingForPermissionNotifiers.clear(); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Geoposition* Geolocation::lastPosition() 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Page* page = this->page(); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!page) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_lastPosition = createGeoposition(GeolocationController::from(page)->lastPosition()); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_lastPosition.get(); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!frame()) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startRequest(notifier.get()); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_oneShots.add(notifier); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!frame()) 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startRequest(notifier.get()); 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 310926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int watchID; 311926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Keep asking for the next id until we're given one that we don't already have. 312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) do { 313ede7d0ec43b4c8737d917f2c5ad872a7b36ca9a8Torne (Richard Coles) watchID = scriptExecutionContext()->circularSequentialID(); 314926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } while (!m_watchers.add(watchID, notifier)); 315926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return watchID; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::startRequest(GeoNotifier *notifier) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check whether permissions have already been denied. Note that if this is the case, 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the permission state can not change again in the lifetime of this page. 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isDenied()) 323d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (haveSuitableCachedPosition(notifier->options())) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifier->setUseCachedPosition(); 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (notifier->hasZeroTimeout()) 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifier->startTimerIfNeeded(); 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!isAllowed()) { 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // if we don't yet have permission, request for permission before calling startUpdating() 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_pendingForPermissionNotifiers.add(notifier); 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) requestPermission(); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (startUpdating(notifier)) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifier->startTimerIfNeeded(); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 335d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This request has failed fatally. Remove it from our lists. 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_oneShots.remove(notifier); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_watchers.remove(notifier); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasListeners()) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier) 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This is called asynchronously, so the permissions could have been denied 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // since we last checked in startRequest. 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isDenied()) { 353d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_requestsAwaitingCachedPosition.add(notifier); 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If permissions are allowed, make the callback 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAllowed()) { 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCachedPositionCallbacks(); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Request permissions, which may be synchronous or asynchronous. 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) requestPermission(); 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::makeCachedPositionCallbacks() 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // All modifications to m_requestsAwaitingCachedPosition are done 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // asynchronously, so we don't need to worry about it being modified from 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the callbacks. 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end(); 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) { 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifier* notifier = iter->get(); 377926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) notifier->runSuccessCallback(lastPosition()); 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this is a one-shot request, stop it. Otherwise, if the watch still 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // exists, start the service to get updates. 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_oneShots.contains(notifier)) 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_oneShots.remove(notifier); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (m_watchers.contains(notifier)) { 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (notifier->hasZeroTimeout() || startUpdating(notifier)) 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifier->startTimerIfNeeded(); 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 387d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_requestsAwaitingCachedPosition.clear(); 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasListeners()) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::requestTimedOut(GeoNotifier* notifier) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If this is a one-shot request, stop it. 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_oneShots.remove(notifier); 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasListeners()) 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Geolocation::haveSuitableCachedPosition(PositionOptions* options) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 408926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) Geoposition* cachedPosition = lastPosition(); 409926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!cachedPosition) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!options->hasMaximumAge()) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!options->maximumAge()) 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DOMTimeStamp currentTimeMillis = convertSecondsToDOMTimeStamp(currentTime()); 416926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return cachedPosition->timestamp() > currentTimeMillis - options->maximumAge(); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 419926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void Geolocation::clearWatch(int watchID) 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 421926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (watchID <= 0) 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 424926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (GeoNotifier* notifier = m_watchers.find(watchID)) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_pendingForPermissionNotifiers.remove(notifier); 426926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_watchers.remove(watchID); 42702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasListeners()) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::setIsAllowed(bool allowed) 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Protect the Geolocation object from garbage collection during a callback. 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<Geolocation> protect(this); 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This may be due to either a new position from the service, or a cached 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // position. 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_allowGeolocation = allowed ? Yes : No; 44002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Permission request was made during the startRequest process 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_pendingForPermissionNotifiers.isEmpty()) { 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) handlePendingPermissionNotifiers(); 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_pendingForPermissionNotifiers.clear(); 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isAllowed()) { 449d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage); 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) error->setIsFatal(true); 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) handleError(error.get()); 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_requestsAwaitingCachedPosition.clear(); 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the service has a last position, use it to call back for all requests. 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If any of the requests are waiting for permission for a cached position, 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the position from the service will be at least as fresh. 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lastPosition()) 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeSuccessCallbacks(); 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeCachedPositionCallbacks(); 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector::const_iterator end = notifiers.end(); 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<GeoNotifier> notifier = *it; 47002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifier->runErrorCallback(error); 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* position) 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector::const_iterator end = notifiers.end(); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (*it)->runSuccessCallback(position); 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::stopTimer(GeoNotifierVector& notifiers) 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector::const_iterator end = notifiers.end(); 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (*it)->stopTimer(); 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::stopTimersForOneShots() 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector copy; 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) copyToVector(m_oneShots, copy); 49302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopTimer(copy); 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::stopTimersForWatchers() 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector copy; 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_watchers.getNotifiersVector(copy); 50102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopTimer(copy); 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::stopTimers() 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopTimersForOneShots(); 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopTimersForWatchers(); 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::cancelRequests(GeoNotifierVector& notifiers) 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector::const_iterator end = notifiers.end(); 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) 515d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch (*it)->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, framelessDocumentErrorMessage)); 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::cancelAllRequests() 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector copy; 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) copyToVector(m_oneShots, copy); 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cancelRequests(copy); 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_watchers.getNotifiersVector(copy); 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cancelRequests(copy); 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached) 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector nonCached; 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector::iterator end = notifiers.end(); 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifier* notifier = it->get(); 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (notifier->useCachedPosition()) { 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cached) 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cached->append(notifier); 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nonCached.append(notifier); 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifiers.swap(nonCached); 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::copyToSet(const GeoNotifierVector& src, GeoNotifierSet& dest) 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector::const_iterator end = src.end(); 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierVector::const_iterator it = src.begin(); it != end; ++it) { 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifier* notifier = it->get(); 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dest.add(notifier); 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::handleError(PositionError* error) 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(error); 55402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector oneShotsCopy; 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) copyToVector(m_oneShots, oneShotsCopy); 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector watchersCopy; 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_watchers.getNotifiersVector(watchersCopy); 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Clear the lists before we make the callbacks, to avoid clearing notifiers 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // added by calls to Geolocation methods from the callbacks, and to prevent 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // further callbacks to these notifiers. 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector oneShotsWithCachedPosition; 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_oneShots.clear(); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (error->isFatal()) 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_watchers.clear(); 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't send non-fatal errors to notifiers due to receive a cached position. 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extractNotifiersWithCachedPosition(oneShotsCopy, &oneShotsWithCachedPosition); 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extractNotifiersWithCachedPosition(watchersCopy, 0); 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sendError(oneShotsCopy, error); 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sendError(watchersCopy, error); 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // hasListeners() doesn't distinguish between notifiers due to receive a 5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // cached position and those requiring a fresh position. Perform the check 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // before restoring the notifiers below. 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasListeners()) 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Maintain a reference to the cached notifiers until their timer fires. 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) copyToSet(oneShotsWithCachedPosition, m_oneShots); 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::requestPermission() 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_allowGeolocation > Unknown) 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Page* page = this->page(); 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!page) 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_allowGeolocation = InProgress; 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ask the embedder: it maintains the geolocation challenge policy itself. 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeolocationController::from(page)->requestPermission(this); 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::makeSuccessCallbacks() 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(lastPosition()); 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isAllowed()); 60602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector oneShotsCopy; 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) copyToVector(m_oneShots, oneShotsCopy); 60902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierVector watchersCopy; 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_watchers.getNotifiersVector(watchersCopy); 61202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Clear the lists before we make the callbacks, to avoid clearing notifiers 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // added by calls to Geolocation methods from the callbacks, and to prevent 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // further callbacks to these notifiers. 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_oneShots.clear(); 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sendPosition(oneShotsCopy, lastPosition()); 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sendPosition(watchersCopy, lastPosition()); 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hasListeners()) 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopUpdating(); 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::positionChanged() 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isAllowed()); 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Stop all currently running timers. 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stopTimers(); 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) makeSuccessCallbacks(); 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::setError(GeolocationError* error) 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<PositionError> positionError = createPositionError(error); 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) handleError(positionError.get()); 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Geolocation::startUpdating(GeoNotifier* notifier) 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Page* page = this->page(); 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!page) 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeolocationController::from(page)->addObserver(this, notifier->options()->enableHighAccuracy()); 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::stopUpdating() 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Page* page = this->page(); 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!page) 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeolocationController::from(page)->removeObserver(this); 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Geolocation::handlePendingPermissionNotifiers() 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 66202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // While we iterate through the list, we need not worry about list being modified as the permission 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // is already set to Yes/No and no new listeners will be added to the pending list 6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end(); 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (GeoNotifierSet::const_iterator iter = m_pendingForPermissionNotifiers.begin(); iter != end; ++iter) { 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GeoNotifier* notifier = iter->get(); 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAllowed()) { 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // start all pending notification requests as permission granted. 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The notifier is always ref'ed by m_oneShots or m_watchers. 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startUpdating(notifier)) 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) notifier->startTimerIfNeeded(); 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 674d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 675d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch } else { 676d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 677d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch } 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 682