18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. 30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 Torch Mobile, Inc. 48a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * Copyright 2010, The Android Open Source Project 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Geolocation.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if ENABLE(GEOLOCATION) 32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Chrome.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Page.h" 36363d073b4eb761499b7bf1d6834b00e9551406e4Steve Block#if PLATFORM(ANDROID) 37930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block#include "PlatformBridge.h" 38363d073b4eb761499b7bf1d6834b00e9551406e4Steve Block#endif 399ca5793315e248418a353cc1443f3803ae0adfe6Steve Block#include <wtf/CurrentTime.h> 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41370b559b082915acb99b185ed8c8e317fc654db6Steve Block#if ENABLE(CLIENT_BASED_GEOLOCATION) 42370b559b082915acb99b185ed8c8e317fc654db6Steve Block#include "Coordinates.h" 43370b559b082915acb99b185ed8c8e317fc654db6Steve Block#include "GeolocationController.h" 44370b559b082915acb99b185ed8c8e317fc654db6Steve Block#include "GeolocationError.h" 45370b559b082915acb99b185ed8c8e317fc654db6Steve Block#include "GeolocationPosition.h" 46370b559b082915acb99b185ed8c8e317fc654db6Steve Block#include "PositionError.h" 47370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 48370b559b082915acb99b185ed8c8e317fc654db6Steve Block 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Blockstatic const char permissionDeniedErrorMessage[] = "User denied Geolocation"; 52159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Blockstatic const char failedToStartServiceErrorMessage[] = "Failed to start Geolocation service"; 53f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickstatic const char framelessDocumentErrorMessage[] = "Geolocation cannot be used in frameless documents"; 54f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 55f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickstatic const int firstAvailableWatchId = 1; 560c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block 57370b559b082915acb99b185ed8c8e317fc654db6Steve Block#if ENABLE(CLIENT_BASED_GEOLOCATION) 58370b559b082915acb99b185ed8c8e317fc654db6Steve Block 59370b559b082915acb99b185ed8c8e317fc654db6Steve Blockstatic PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position) 60370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 61db217ef7ffee230d812f9da02a02d7d7bc696a8dSteve Block if (!position) 62db217ef7ffee230d812f9da02a02d7d7bc696a8dSteve Block return 0; 63db217ef7ffee230d812f9da02a02d7d7bc696a8dSteve Block 64370b559b082915acb99b185ed8c8e317fc654db6Steve Block RefPtr<Coordinates> coordinates = Coordinates::create(position->latitude(), position->longitude(), position->canProvideAltitude(), position->altitude(), 65370b559b082915acb99b185ed8c8e317fc654db6Steve Block position->accuracy(), position->canProvideAltitudeAccuracy(), position->altitudeAccuracy(), 66370b559b082915acb99b185ed8c8e317fc654db6Steve Block position->canProvideHeading(), position->heading(), position->canProvideSpeed(), position->speed()); 676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return Geoposition::create(coordinates.release(), convertSecondsToDOMTimeStamp(position->timestamp())); 68370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 69370b559b082915acb99b185ed8c8e317fc654db6Steve Block 70370b559b082915acb99b185ed8c8e317fc654db6Steve Blockstatic PassRefPtr<PositionError> createPositionError(GeolocationError* error) 71370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 72370b559b082915acb99b185ed8c8e317fc654db6Steve Block PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE; 73370b559b082915acb99b185ed8c8e317fc654db6Steve Block switch (error->code()) { 74370b559b082915acb99b185ed8c8e317fc654db6Steve Block case GeolocationError::PermissionDenied: 75370b559b082915acb99b185ed8c8e317fc654db6Steve Block code = PositionError::PERMISSION_DENIED; 76370b559b082915acb99b185ed8c8e317fc654db6Steve Block break; 77370b559b082915acb99b185ed8c8e317fc654db6Steve Block case GeolocationError::PositionUnavailable: 78370b559b082915acb99b185ed8c8e317fc654db6Steve Block code = PositionError::POSITION_UNAVAILABLE; 79370b559b082915acb99b185ed8c8e317fc654db6Steve Block break; 80370b559b082915acb99b185ed8c8e317fc654db6Steve Block } 81370b559b082915acb99b185ed8c8e317fc654db6Steve Block 82370b559b082915acb99b185ed8c8e317fc654db6Steve Block return PositionError::create(code, error->message()); 83370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 84370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 85370b559b082915acb99b185ed8c8e317fc654db6Steve Block 860c97c982f069c9d9eee236d7f8461710d2e1d078Steve BlockGeolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 870c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block : m_geolocation(geolocation) 880c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block , m_successCallback(successCallback) 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_errorCallback(errorCallback) 905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_options(options) 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_timer(this, &Geolocation::GeoNotifier::timerFired) 9295b5322fb41833173e2aa950c094b58ee83c1a16Steve Block , m_useCachedPosition(false) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 940c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block ASSERT(m_geolocation); 956453d21822fbf87a3fec6a6351a56933d2d9d730Steve Block ASSERT(m_successCallback); 966453d21822fbf87a3fec6a6351a56933d2d9d730Steve Block // If no options were supplied from JS, we should have created a default set 976453d21822fbf87a3fec6a6351a56933d2d9d730Steve Block // of options in JSGeolocationCustom.cpp. 986453d21822fbf87a3fec6a6351a56933d2d9d730Steve Block ASSERT(m_options); 995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 1005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1010c97c982f069c9d9eee236d7f8461710d2e1d078Steve Blockvoid Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error) 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 103f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // If a fatal error has already been set, stick with it. This makes sure that 104f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // when permission is denied, this is the error reported, as required by the 105f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // spec. 106f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (m_fatalError) 107f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return; 108f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 1090c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block m_fatalError = error; 110f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // An existing timer may not have a zero timeout. 111f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_timer.stop(); 1120c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block m_timer.startOneShot(0); 1135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 1145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 115a8d4462216d8e009ee5662660a0621b67c6e727fSteve Blockvoid Geolocation::GeoNotifier::setUseCachedPosition() 116bc2cb6973923b5560298950bd824d9627d6ed765Steve Block{ 117a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block m_useCachedPosition = true; 118bc2cb6973923b5560298950bd824d9627d6ed765Steve Block m_timer.startOneShot(0); 119bc2cb6973923b5560298950bd824d9627d6ed765Steve Block} 120bc2cb6973923b5560298950bd824d9627d6ed765Steve Block 121159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Blockbool Geolocation::GeoNotifier::hasZeroTimeout() const 122159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block{ 123159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block return m_options->hasTimeout() && m_options->timeout() == 0; 124159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block} 125159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block 126159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Blockvoid Geolocation::GeoNotifier::runSuccessCallback(Geoposition* position) 127a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block{ 128a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block m_successCallback->handleEvent(position); 129a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block} 130a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block 131802cd652fedb21e935bc514406bd7f5cc83de64dSteve Blockvoid Geolocation::GeoNotifier::startTimerIfNeeded() 1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 133802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block if (m_options->hasTimeout()) 1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_timer.startOneShot(m_options->timeout() / 1000.0); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.stop(); 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1411c58588a98d412c23d74caf92991904fddbc9d49Steve Block // Protect this GeoNotifier object, since it 142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // could be deleted by a call to clearWatch in a callback. 1431c58588a98d412c23d74caf92991904fddbc9d49Steve Block RefPtr<GeoNotifier> protect(this); 1444cde69e96bdfa8e4abe06985ab19e407696539cfSteve Block 145f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Test for fatal error first. This is required for the case where the Frame is 146f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // disconnected and requests are cancelled. 1470c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block if (m_fatalError) { 148bc2cb6973923b5560298950bd824d9627d6ed765Steve Block if (m_errorCallback) 1490c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block m_errorCallback->handleEvent(m_fatalError.get()); 1500c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block // This will cause this notifier to be deleted. 1511c58588a98d412c23d74caf92991904fddbc9d49Steve Block m_geolocation->fatalErrorOccurred(this); 1520c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block return; 1530c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block } 1540c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block 155a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block if (m_useCachedPosition) { 156a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block // Clear the cached position flag in case this is a watch request, which 157c7d0c5294bbef1855c84c8072058813371f1af16Steve Block // will continue to run. 158a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block m_useCachedPosition = false; 159a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block m_geolocation->requestUsesCachedPosition(this); 160bc2cb6973923b5560298950bd824d9627d6ed765Steve Block return; 161bc2cb6973923b5560298950bd824d9627d6ed765Steve Block } 162bc2cb6973923b5560298950bd824d9627d6ed765Steve Block 163802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block if (m_errorCallback) { 164466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired"); 165802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block m_errorCallback->handleEvent(error.get()); 166802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block } 1671c58588a98d412c23d74caf92991904fddbc9d49Steve Block m_geolocation->requestTimedOut(this); 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 170643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid Geolocation::Watchers::set(int id, PassRefPtr<GeoNotifier> prpNotifier) 171466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block{ 172f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT(id > 0); 173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block RefPtr<GeoNotifier> notifier = prpNotifier; 174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_idToNotifierMap.set(id, notifier.get()); 176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block m_notifierToIdMap.set(notifier.release(), id); 177466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block} 178466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 179466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Blockvoid Geolocation::Watchers::remove(int id) 180466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block{ 181f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT(id > 0); 182466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block IdToNotifierMap::iterator iter = m_idToNotifierMap.find(id); 183466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block if (iter == m_idToNotifierMap.end()) 184466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block return; 185466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_notifierToIdMap.remove(iter->second); 186466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_idToNotifierMap.remove(iter); 187466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block} 188466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 189466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Blockvoid Geolocation::Watchers::remove(GeoNotifier* notifier) 190466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block{ 191466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block NotifierToIdMap::iterator iter = m_notifierToIdMap.find(notifier); 192466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block if (iter == m_notifierToIdMap.end()) 193466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block return; 194466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_idToNotifierMap.remove(iter->second); 195466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_notifierToIdMap.remove(iter); 196466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block} 197466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 19895e7487cbe7ec5c780e8af61f3cea2d90bb4459bSteve Blockbool Geolocation::Watchers::contains(GeoNotifier* notifier) const 19995e7487cbe7ec5c780e8af61f3cea2d90bb4459bSteve Block{ 20095e7487cbe7ec5c780e8af61f3cea2d90bb4459bSteve Block return m_notifierToIdMap.contains(notifier); 20195e7487cbe7ec5c780e8af61f3cea2d90bb4459bSteve Block} 20295e7487cbe7ec5c780e8af61f3cea2d90bb4459bSteve Block 203466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Blockvoid Geolocation::Watchers::clear() 204466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block{ 205466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_idToNotifierMap.clear(); 206466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_notifierToIdMap.clear(); 207466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block} 208466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 209466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Blockbool Geolocation::Watchers::isEmpty() const 210466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block{ 211466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block return m_idToNotifierMap.isEmpty(); 212466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block} 213466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 2146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid Geolocation::Watchers::getNotifiersVector(GeoNotifierVector& copy) const 215466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block{ 216466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block copyValuesToVector(m_idToNotifierMap, copy); 217466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block} 218466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectGeolocation::Geolocation(Frame* frame) 220400e786798d320e3c9f4c9d82ea18ecc492a525aSteve Block : m_frame(frame) 221370b559b082915acb99b185ed8c8e317fc654db6Steve Block#if !ENABLE(CLIENT_BASED_GEOLOCATION) 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_service(GeolocationService::create(this)) 223370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_allowGeolocation(Unknown) 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!m_frame) 2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_frame->document()); 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame->document()->setUsingGeolocation(true); 2300c7394a4459ba850766d303b4307add7189cf5f3Steve Block} 2310c7394a4459ba850766d303b4307add7189cf5f3Steve Block 2320c7394a4459ba850766d303b4307add7189cf5f3Steve BlockGeolocation::~Geolocation() 2330c7394a4459ba850766d303b4307add7189cf5f3Steve Block{ 2342bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(m_allowGeolocation != InProgress); 2352bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(!m_frame); 236400e786798d320e3c9f4c9d82ea18ecc492a525aSteve Block} 237400e786798d320e3c9f4c9d82ea18ecc492a525aSteve Block 2382bde8e466a4451c7319e3a072d118917957d6554Steve BlockPage* Geolocation::page() const 2392bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2402bde8e466a4451c7319e3a072d118917957d6554Steve Block return m_frame ? m_frame->page() : 0; 2412bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2422bde8e466a4451c7319e3a072d118917957d6554Steve Block 2432bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid Geolocation::reset() 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2452bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = this->page(); 2462bde8e466a4451c7319e3a072d118917957d6554Steve Block if (page && m_allowGeolocation == InProgress) { 247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if ENABLE(CLIENT_BASED_GEOLOCATION) 2482bde8e466a4451c7319e3a072d118917957d6554Steve Block page->geolocationController()->cancelPermissionRequest(this); 249f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 2502bde8e466a4451c7319e3a072d118917957d6554Steve Block page->chrome()->cancelGeolocationPermissionRequestForFrame(m_frame, this); 251f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 2532bde8e466a4451c7319e3a072d118917957d6554Steve Block // The frame may be moving to a new page and we want to get the permissions from the new page's client. 2542bde8e466a4451c7319e3a072d118917957d6554Steve Block m_allowGeolocation = Unknown; 255f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick cancelAllRequests(); 2565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke stopUpdating(); 2572bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2582bde8e466a4451c7319e3a072d118917957d6554Steve Block 2592bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid Geolocation::disconnectFrame() 2602bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 2612bde8e466a4451c7319e3a072d118917957d6554Steve Block // Once we are disconnected from the Frame, it is no longer possible to perform any operations. 2622bde8e466a4451c7319e3a072d118917957d6554Steve Block reset(); 263eebae91469b8f225fe78e97ce6dae26efcf6da43Steve Block if (m_frame && m_frame->document()) 264eebae91469b8f225fe78e97ce6dae26efcf6da43Steve Block m_frame->document()->setUsingGeolocation(false); 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_frame = 0; 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268370b559b082915acb99b185ed8c8e317fc654db6Steve BlockGeoposition* Geolocation::lastPosition() 269370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 270370b559b082915acb99b185ed8c8e317fc654db6Steve Block#if ENABLE(CLIENT_BASED_GEOLOCATION) 2712bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = this->page(); 272370b559b082915acb99b185ed8c8e317fc654db6Steve Block if (!page) 273370b559b082915acb99b185ed8c8e317fc654db6Steve Block return 0; 274370b559b082915acb99b185ed8c8e317fc654db6Steve Block 275370b559b082915acb99b185ed8c8e317fc654db6Steve Block m_lastPosition = createGeoposition(page->geolocationController()->lastPosition()); 276370b559b082915acb99b185ed8c8e317fc654db6Steve Block#else 277370b559b082915acb99b185ed8c8e317fc654db6Steve Block m_lastPosition = m_service->lastPosition(); 278370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 279370b559b082915acb99b185ed8c8e317fc654db6Steve Block 280370b559b082915acb99b185ed8c8e317fc654db6Steve Block return m_lastPosition.get(); 281370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 282370b559b082915acb99b185ed8c8e317fc654db6Steve Block 2835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 285f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!m_frame) 286f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return; 287f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 288466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options); 2894abe833d66929ee0f0363cf63dfe35ffe3d5a0a2Steve Block ASSERT(notifier); 2903ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block 2913ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block m_oneShots.add(notifier); 2923ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block} 2933ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block 2943ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Blockint Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 2953ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block{ 296f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!m_frame) 297f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return 0; 298f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 299466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options); 3004abe833d66929ee0f0363cf63dfe35ffe3d5a0a2Steve Block ASSERT(notifier); 3013ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block 302f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick static int nextAvailableWatchId = firstAvailableWatchId; 303cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // In case of overflow, make sure the ID remains positive, but reuse the ID values. 304cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (nextAvailableWatchId < 1) 305cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block nextAvailableWatchId = 1; 306466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_watchers.set(nextAvailableWatchId, notifier.release()); 307466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block return nextAvailableWatchId++; 3083ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block} 3093ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block 310466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve BlockPassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options) 3113ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block{ 3120c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options); 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3140c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block // Check whether permissions have already been denied. Note that if this is the case, 3150c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block // the permission state can not change again in the lifetime of this page. 316466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block if (isDenied()) 3173ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 318159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block else if (haveSuitableCachedPosition(notifier->m_options.get())) 319159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block notifier->setUseCachedPosition(); 320f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick else if (notifier->hasZeroTimeout()) 321f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick notifier->startTimerIfNeeded(); 322967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if USE(PREEMPT_GEOLOCATION_PERMISSION) 323f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick else if (!isAllowed()) { 324f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // if we don't yet have permission, request for permission before calling startUpdating() 325f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_pendingForPermissionNotifiers.add(notifier); 326f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick requestPermission(); 327f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 328f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#endif 329f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick else if (startUpdating(notifier.get())) 330f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick notifier->startTimerIfNeeded(); 331f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick else 332159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3343ae77a67311f7f1a6a072ccb81b5f502b09e4fb2Steve Block return notifier.release(); 3350c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block} 3360c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block 3370c97c982f069c9d9eee236d7f8461710d2e1d078Steve Blockvoid Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier) 3380c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block{ 3390c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block // This request has failed fatally. Remove it from our lists. 3400c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block m_oneShots.remove(notifier); 341466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_watchers.remove(notifier); 3420c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block 3430c97c982f069c9d9eee236d7f8461710d2e1d078Steve Block if (!hasListeners()) 344370b559b082915acb99b185ed8c8e317fc654db6Steve Block stopUpdating(); 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 347a8d4462216d8e009ee5662660a0621b67c6e727fSteve Blockvoid Geolocation::requestUsesCachedPosition(GeoNotifier* notifier) 348159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block{ 349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This is called asynchronously, so the permissions could have been denied 350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // since we last checked in startRequest. 351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (isDenied()) { 352dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 355dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 356dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_requestsAwaitingCachedPosition.add(notifier); 357dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 358dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // If permissions are allowed, make the callback 359dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (isAllowed()) { 360dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block makeCachedPositionCallbacks(); 361dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 362dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 363dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 364dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Request permissions, which may be synchronous or asynchronous. 365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block requestPermission(); 366dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 367dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid Geolocation::makeCachedPositionCallbacks() 369dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 370dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // All modifications to m_requestsAwaitingCachedPosition are done 371dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // asynchronously, so we don't need to worry about it being modified from 372dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // the callbacks. 373dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end(); 374dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) { 375dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GeoNotifier* notifier = iter->get(); 376f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch notifier->runSuccessCallback(m_positionCache.cachedPosition()); 377dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 378dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // If this is a one-shot request, stop it. Otherwise, if the watch still 379dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // exists, start the service to get updates. 380dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_oneShots.contains(notifier)) 381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_oneShots.remove(notifier); 382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (m_watchers.contains(notifier)) { 383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (notifier->hasZeroTimeout() || startUpdating(notifier)) 384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block notifier->startTimerIfNeeded(); 385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else 386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_requestsAwaitingCachedPosition.clear(); 391159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block 392159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block if (!hasListeners()) 393159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block stopUpdating(); 394159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block} 395159531f4ce4c04455cd544a7c0f7c1644a50ccbeSteve Block 396dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid Geolocation::requestTimedOut(GeoNotifier* notifier) 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 398dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // If this is a one-shot request, stop it. 399dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_oneShots.remove(notifier); 400dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasListeners()) 402370b559b082915acb99b185ed8c8e317fc654db6Steve Block stopUpdating(); 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 405dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool Geolocation::haveSuitableCachedPosition(PositionOptions* options) 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_positionCache.cachedPosition()) 408dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!options->hasMaximumAge()) 410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return true; 411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!options->maximumAge()) 412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return false; 4136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner DOMTimeStamp currentTimeMillis = convertSecondsToDOMTimeStamp(currentTime()); 414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_positionCache.cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge(); 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid Geolocation::clearWatch(int watchId) 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 419f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (watchId < firstAvailableWatchId) 420f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return; 421f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 422dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_watchers.remove(watchId); 423dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 424dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!hasListeners()) 425dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block stopUpdating(); 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4285fb15a120c24faef11e5952a791c5af38c54b07eSteve Blockvoid Geolocation::suspend() 4295fb15a120c24faef11e5952a791c5af38c54b07eSteve Block{ 4305fb15a120c24faef11e5952a791c5af38c54b07eSteve Block#if !ENABLE(CLIENT_BASED_GEOLOCATION) 4315fb15a120c24faef11e5952a791c5af38c54b07eSteve Block if (hasListeners()) 4325fb15a120c24faef11e5952a791c5af38c54b07eSteve Block m_service->suspend(); 4335fb15a120c24faef11e5952a791c5af38c54b07eSteve Block#endif 4345fb15a120c24faef11e5952a791c5af38c54b07eSteve Block} 4355fb15a120c24faef11e5952a791c5af38c54b07eSteve Block 4365fb15a120c24faef11e5952a791c5af38c54b07eSteve Blockvoid Geolocation::resume() 4375fb15a120c24faef11e5952a791c5af38c54b07eSteve Block{ 4385fb15a120c24faef11e5952a791c5af38c54b07eSteve Block#if !ENABLE(CLIENT_BASED_GEOLOCATION) 4395fb15a120c24faef11e5952a791c5af38c54b07eSteve Block if (hasListeners()) 4405fb15a120c24faef11e5952a791c5af38c54b07eSteve Block m_service->resume(); 4415fb15a120c24faef11e5952a791c5af38c54b07eSteve Block#endif 4425fb15a120c24faef11e5952a791c5af38c54b07eSteve Block} 4435fb15a120c24faef11e5952a791c5af38c54b07eSteve Block 4448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid Geolocation::setIsAllowed(bool allowed) 4458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 446bc2cb6973923b5560298950bd824d9627d6ed765Steve Block // This may be due to either a new position from the service, or a cached 447bc2cb6973923b5560298950bd824d9627d6ed765Steve Block // position. 4488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_allowGeolocation = allowed ? Yes : No; 44923c22a60ec108914d8df8cd80023582fbedfe978Steve Block 450967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if USE(PREEMPT_GEOLOCATION_PERMISSION) 451f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Permission request was made during the startRequest process 452f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!m_pendingForPermissionNotifiers.isEmpty()) { 453f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick handlePendingPermissionNotifiers(); 454f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_pendingForPermissionNotifiers.clear(); 45523c22a60ec108914d8df8cd80023582fbedfe978Steve Block return; 45623c22a60ec108914d8df8cd80023582fbedfe978Steve Block } 45723c22a60ec108914d8df8cd80023582fbedfe978Steve Block#endif 458bc2cb6973923b5560298950bd824d9627d6ed765Steve Block 459bc2cb6973923b5560298950bd824d9627d6ed765Steve Block if (!isAllowed()) { 460466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage); 4615343011d8c5e322c74a78385633354ca3db92343Steve Block error->setIsFatal(true); 4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian handleError(error.get()); 463a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block m_requestsAwaitingCachedPosition.clear(); 464bc2cb6973923b5560298950bd824d9627d6ed765Steve Block return; 4658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 466bc2cb6973923b5560298950bd824d9627d6ed765Steve Block 467bc2cb6973923b5560298950bd824d9627d6ed765Steve Block // If the service has a last position, use it to call back for all requests. 468bc2cb6973923b5560298950bd824d9627d6ed765Steve Block // If any of the requests are waiting for permission for a cached position, 469bc2cb6973923b5560298950bd824d9627d6ed765Steve Block // the position from the service will be at least as fresh. 4708a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (lastPosition()) 471bc2cb6973923b5560298950bd824d9627d6ed765Steve Block makeSuccessCallbacks(); 472a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block else 473a8d4462216d8e009ee5662660a0621b67c6e727fSteve Block makeCachedPositionCallbacks(); 4748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 4758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) 4770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 4786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector::const_iterator end = notifiers.end(); 4796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { 4800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RefPtr<GeoNotifier> notifier = *it; 4810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (notifier->m_errorCallback) 4830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch notifier->m_errorCallback->handleEvent(error); 4840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 4850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 4860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* position) 4880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 4896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector::const_iterator end = notifiers.end(); 4906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<GeoNotifier> notifier = *it; 4920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(notifier->m_successCallback); 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch notifier->m_successCallback->handleEvent(position); 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid Geolocation::stopTimer(GeoNotifierVector& notifiers) 4995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 5006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector::const_iterator end = notifiers.end(); 5016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { 5025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RefPtr<GeoNotifier> notifier = *it; 503802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block notifier->m_timer.stop(); 5045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 5065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 507802cd652fedb21e935bc514406bd7f5cc83de64dSteve Blockvoid Geolocation::stopTimersForOneShots() 5085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 5096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector copy; 5105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian copyToVector(m_oneShots, copy); 5115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 512802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block stopTimer(copy); 5135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 5145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 515802cd652fedb21e935bc514406bd7f5cc83de64dSteve Blockvoid Geolocation::stopTimersForWatchers() 5165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 5176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector copy; 518466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_watchers.getNotifiersVector(copy); 5195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 520802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block stopTimer(copy); 5215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 5225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 523802cd652fedb21e935bc514406bd7f5cc83de64dSteve Blockvoid Geolocation::stopTimers() 5245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 525802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block stopTimersForOneShots(); 526802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block stopTimersForWatchers(); 5275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 5285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid Geolocation::cancelRequests(GeoNotifierVector& notifiers) 530f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 5316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector::const_iterator end = notifiers.end(); 5326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) 533f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick (*it)->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, framelessDocumentErrorMessage)); 534f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 535f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 536f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid Geolocation::cancelAllRequests() 537f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 5386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector copy; 539f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick copyToVector(m_oneShots, copy); 540f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick cancelRequests(copy); 541f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick m_watchers.getNotifiersVector(copy); 542f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick cancelRequests(copy); 543f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 544f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 5454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid Geolocation::extractNotifiersWithCachedPosition(GeoNotifierVector& notifiers, GeoNotifierVector* cached) 5464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{ 5474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GeoNotifierVector nonCached; 5484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GeoNotifierVector::iterator end = notifiers.end(); 5494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++it) { 5504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GeoNotifier* notifier = it->get(); 5514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (notifier->m_useCachedPosition) { 5524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (cached) 5534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang cached->append(notifier); 5544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } else 5554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang nonCached.append(notifier); 5564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 5574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang notifiers.swap(nonCached); 5584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang} 5594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 5604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangvoid Geolocation::copyToSet(const GeoNotifierVector& src, GeoNotifierSet& dest) 5614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{ 5624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GeoNotifierVector::const_iterator end = src.end(); 5634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang for (GeoNotifierVector::const_iterator it = src.begin(); it != end; ++it) { 5644576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GeoNotifier* notifier = it->get(); 5654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang dest.add(notifier); 5664576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 5674576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang} 5684576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Geolocation::handleError(PositionError* error) 5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(error); 572466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 5736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector oneShotsCopy; 574e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block copyToVector(m_oneShots, oneShotsCopy); 575e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block 5766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector watchersCopy; 577466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_watchers.getNotifiersVector(watchersCopy); 578e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block 579e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block // Clear the lists before we make the callbacks, to avoid clearing notifiers 580466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block // added by calls to Geolocation methods from the callbacks, and to prevent 581466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block // further callbacks to these notifiers. 5824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang GeoNotifierVector oneShotsWithCachedPosition; 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_oneShots.clear(); 5845343011d8c5e322c74a78385633354ca3db92343Steve Block if (error->isFatal()) 5855343011d8c5e322c74a78385633354ca3db92343Steve Block m_watchers.clear(); 5864576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang else { 5874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Don't send non-fatal errors to notifiers due to receive a cached position. 5884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang extractNotifiersWithCachedPosition(oneShotsCopy, &oneShotsWithCachedPosition); 5894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang extractNotifiersWithCachedPosition(watchersCopy, 0); 5904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 5910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 592e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block sendError(oneShotsCopy, error); 593e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block sendError(watchersCopy, error); 594e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block 5954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // hasListeners() doesn't distinguish between notifiers due to receive a 5964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // cached position and those requiring a fresh position. Perform the check 5974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // before restoring the notifiers below. 5980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!hasListeners()) 599370b559b082915acb99b185ed8c8e317fc654db6Steve Block stopUpdating(); 6004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Maintain a reference to the cached notifiers until their timer fires. 6024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang copyToSet(oneShotsWithCachedPosition, m_oneShots); 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid Geolocation::requestPermission() 6068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 6078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m_allowGeolocation > Unknown) 6088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 6098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6102bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = this->page(); 6118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (!page) 6128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 6136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 6140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_allowGeolocation = InProgress; 6150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 616f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Ask the embedder: it maintains the geolocation challenge policy itself. 617f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if ENABLE(CLIENT_BASED_GEOLOCATION) 618f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch page->geolocationController()->requestPermission(this); 619f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else 6208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian page->chrome()->requestGeolocationPermissionForFrame(m_frame, this); 621f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 6228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 6238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 6246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid Geolocation::positionChangedInternal() 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 626f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_positionCache.setCachedPosition(lastPosition()); 62700bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block 628802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block // Stop all currently running timers. 629802cd652fedb21e935bc514406bd7f5cc83de64dSteve Block stopTimers(); 6306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 63100bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block if (!isAllowed()) { 63200bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block // requestPermission() will ask the chrome for permission. This may be 63300bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block // implemented synchronously or asynchronously. In both cases, 634466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block // makeSuccessCallbacks() will be called if permission is granted, so 63500bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block // there's nothing more to do here. 63600bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block requestPermission(); 6378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return; 63800bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block } 63900bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block 64000bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block makeSuccessCallbacks(); 64100bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block} 64200bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block 64300bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Blockvoid Geolocation::makeSuccessCallbacks() 64400bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block{ 645dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(lastPosition()); 64600bd0fc337f03c8595ccae3a2d3d56c6d8e97cc9Steve Block ASSERT(isAllowed()); 647466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 6486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector oneShotsCopy; 649e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block copyToVector(m_oneShots, oneShotsCopy); 650466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 6516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner GeoNotifierVector watchersCopy; 652466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block m_watchers.getNotifiersVector(watchersCopy); 653466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block 654e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block // Clear the lists before we make the callbacks, to avoid clearing notifiers 655466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block // added by calls to Geolocation methods from the callbacks, and to prevent 656466006e4a13fd557d7b35c1fe0b7a38384e5ce2eSteve Block // further callbacks to these notifiers. 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_oneShots.clear(); 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 659dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block sendPosition(oneShotsCopy, lastPosition()); 660dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block sendPosition(watchersCopy, lastPosition()); 661e27fedc48d78b1c1b6e656fe42d64efd60056464Steve Block 6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!hasListeners()) 663370b559b082915acb99b185ed8c8e317fc654db6Steve Block stopUpdating(); 664370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 665370b559b082915acb99b185ed8c8e317fc654db6Steve Block 666370b559b082915acb99b185ed8c8e317fc654db6Steve Block#if ENABLE(CLIENT_BASED_GEOLOCATION) 667370b559b082915acb99b185ed8c8e317fc654db6Steve Block 6686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid Geolocation::positionChanged() 669370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 6706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen positionChangedInternal(); 671370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 672370b559b082915acb99b185ed8c8e317fc654db6Steve Block 673370b559b082915acb99b185ed8c8e317fc654db6Steve Blockvoid Geolocation::setError(GeolocationError* error) 674370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 675370b559b082915acb99b185ed8c8e317fc654db6Steve Block RefPtr<PositionError> positionError = createPositionError(error); 676370b559b082915acb99b185ed8c8e317fc654db6Steve Block handleError(positionError.get()); 677370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 678370b559b082915acb99b185ed8c8e317fc654db6Steve Block 679370b559b082915acb99b185ed8c8e317fc654db6Steve Block#else 680370b559b082915acb99b185ed8c8e317fc654db6Steve Block 681370b559b082915acb99b185ed8c8e317fc654db6Steve Blockvoid Geolocation::geolocationServicePositionChanged(GeolocationService* service) 682370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 683370b559b082915acb99b185ed8c8e317fc654db6Steve Block ASSERT_UNUSED(service, service == m_service); 684370b559b082915acb99b185ed8c8e317fc654db6Steve Block ASSERT(m_service->lastPosition()); 685370b559b082915acb99b185ed8c8e317fc654db6Steve Block 6866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen positionChangedInternal(); 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Geolocation::geolocationServiceErrorOccurred(GeolocationService* service) 6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(service->lastError()); 692370b559b082915acb99b185ed8c8e317fc654db6Steve Block 693c7d0c5294bbef1855c84c8072058813371f1af16Steve Block // Note that we do not stop timers here. For one-shots, the request is 694c7d0c5294bbef1855c84c8072058813371f1af16Steve Block // cleared in handleError. For watchers, the spec requires that the timer is 695c7d0c5294bbef1855c84c8072058813371f1af16Steve Block // not cleared. 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project handleError(service->lastError()); 6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 699370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 700370b559b082915acb99b185ed8c8e317fc654db6Steve Block 70123c22a60ec108914d8df8cd80023582fbedfe978Steve Blockbool Geolocation::startUpdating(GeoNotifier* notifier) 702370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 703967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(CLIENT_BASED_GEOLOCATION) 7042bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = this->page(); 705370b559b082915acb99b185ed8c8e317fc654db6Steve Block if (!page) 706370b559b082915acb99b185ed8c8e317fc654db6Steve Block return false; 707370b559b082915acb99b185ed8c8e317fc654db6Steve Block 7080617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen page->geolocationController()->addObserver(this, notifier->m_options->enableHighAccuracy()); 709370b559b082915acb99b185ed8c8e317fc654db6Steve Block return true; 710370b559b082915acb99b185ed8c8e317fc654db6Steve Block#else 711930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block#if PLATFORM(ANDROID) 712930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082 713930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block // Note that the correct fix is to use a 'paused' flag in WebCore, rather 714930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block // than calling into PlatformBridge. 715b9362877ccf9e5f8027f12898166d56518bbedb6Steve Block if (!m_frame) 716b9362877ccf9e5f8027f12898166d56518bbedb6Steve Block return false; 717b9362877ccf9e5f8027f12898166d56518bbedb6Steve Block FrameView* view = m_frame->view(); 718b9362877ccf9e5f8027f12898166d56518bbedb6Steve Block if (!view) 719b9362877ccf9e5f8027f12898166d56518bbedb6Steve Block return false; 720b9362877ccf9e5f8027f12898166d56518bbedb6Steve Block return m_service->startUpdating(notifier->m_options.get(), PlatformBridge::isWebViewPaused(view)); 721930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block#else 722db42c078ffb0f6a679e3853cb4ebb39e09c1f815Steve Block return m_service->startUpdating(notifier->m_options.get()); 723370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 724930792dfdde9ad0fac3251ab70eb00d97f2fe88dSteve Block#endif 725370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 726370b559b082915acb99b185ed8c8e317fc654db6Steve Block 727370b559b082915acb99b185ed8c8e317fc654db6Steve Blockvoid Geolocation::stopUpdating() 728370b559b082915acb99b185ed8c8e317fc654db6Steve Block{ 729370b559b082915acb99b185ed8c8e317fc654db6Steve Block#if ENABLE(CLIENT_BASED_GEOLOCATION) 7302bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = this->page(); 731370b559b082915acb99b185ed8c8e317fc654db6Steve Block if (!page) 732370b559b082915acb99b185ed8c8e317fc654db6Steve Block return; 733370b559b082915acb99b185ed8c8e317fc654db6Steve Block 734370b559b082915acb99b185ed8c8e317fc654db6Steve Block page->geolocationController()->removeObserver(this); 735370b559b082915acb99b185ed8c8e317fc654db6Steve Block#else 736370b559b082915acb99b185ed8c8e317fc654db6Steve Block m_service->stopUpdating(); 737370b559b082915acb99b185ed8c8e317fc654db6Steve Block#endif 738370b559b082915acb99b185ed8c8e317fc654db6Steve Block 739370b559b082915acb99b185ed8c8e317fc654db6Steve Block} 740370b559b082915acb99b185ed8c8e317fc654db6Steve Block 741f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#if USE(PREEMPT_GEOLOCATION_PERMISSION) 742f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid Geolocation::handlePendingPermissionNotifiers() 743f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 744f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // While we iterate through the list, we need not worry about list being modified as the permission 745f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // is already set to Yes/No and no new listeners will be added to the pending list 746f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end(); 747f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (GeoNotifierSet::const_iterator iter = m_pendingForPermissionNotifiers.begin(); iter != end; ++iter) { 748f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick GeoNotifier* notifier = iter->get(); 749f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 750f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (isAllowed()) { 751f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // start all pending notification requests as permission granted. 752f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // The notifier is always ref'ed by m_oneShots or m_watchers. 753e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (startUpdating(notifier)) 754e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifier->startTimerIfNeeded(); 755e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block else 756e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 757f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } else 758f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 759f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 760f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 761f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#endif 762f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 764dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 765dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#else 766dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 767dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocknamespace WebCore { 768dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 769a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid Geolocation::clearWatch(int) {} 77021939df44de1705786c545cd1bf519d47250322dBen Murdoch 7712bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid Geolocation::reset() {} 7722bde8e466a4451c7319e3a072d118917957d6554Steve Block 773dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid Geolocation::disconnectFrame() {} 774dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 775dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGeolocation::Geolocation(Frame*) {} 776dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 777dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGeolocation::~Geolocation() {} 778dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 779dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid Geolocation::setIsAllowed(bool) {} 780dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 781dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 782dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 783dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif // ENABLE(GEOLOCATION) 784