Changeset 55841 in webkit
- Timestamp:
- Mar 11, 2010, 3:38:39 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r55840 r55841 1 2010-03-10 Steve Block <steveblock@google.com> 2 3 Reviewed by Jeremy Orlow. 4 5 Implements Geolocation maximumAge property 6 https://bugs.webkit.org/show_bug.cgi?id=30676 7 8 * fast/dom/Geolocation/resources/maximum-age.js: Added. Checks that a cached position is used only when it should be. 9 * fast/dom/Geolocation/maximum-age.html: Added. HTML wraper for above test. 10 * fast/dom/Geolocation/maximum-age-expected.txt: Added. Expected result for above test. 11 1 12 2010-03-11 Philippe Normand <pnormand@igalia.com> 2 13 -
trunk/WebCore/ChangeLog
r55838 r55841 1 2010-03-10 Steve Block <steveblock@google.com> 2 3 Reviewed by Jeremy Orlow. 4 5 Implements Geolocation maximumAge property 6 https://bugs.webkit.org/show_bug.cgi?id=30676 7 8 Test: fast/dom/Geolocation/maximum-age.html 9 10 * WebCore.xcodeproj/project.pbxproj: Modified. Adds GeolocationPositionCache.h to Private headers 11 * page/Geolocation.cpp: Modified. 12 (WebCore::Geolocation::GeoNotifier::setUseCachedPosition): Added. 13 (WebCore::Geolocation::GeoNotifier::runSuccessCallback): Added. 14 (WebCore::Geolocation::GeoNotifier::timerFired): Modified. Added logic to handle using a cached position 15 (WebCore::Geolocation::Watchers::contains): Added. Required to determine if a notifier is a watch request 16 (WebCore::Geolocation::startRequest): Modified. Added logic to check for a cached position 17 (WebCore::Geolocation::requestUsesCachedPosition): Added. Callback to Geolocation object when notifier uses a cached position 18 (WebCore::Geolocation::makeCachedPositionCallbacks): Added. 19 (WebCore::Geolocation::haveSuitableCachedPosition): Added. 20 (WebCore::Geolocation::setIsAllowed): Modified. 21 (WebCore::Geolocation::positionChanged): Modified. Make callbacks using cached position where appropriate 22 (WebCore::Geolocation::geolocationServiceErrorOccurred): Modified. Make callbacks using cached position where appropriate 23 * page/Geolocation.h: Modified. 24 1 25 2010-03-11 Csaba Osztrogonác <ossy@webkit.org> 2 26 -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r55825 r55841 1124 1124 5913953D1107584E0083EC55 /* JNIBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5913953C1107584E0083EC55 /* JNIBridge.cpp */; }; 1125 1125 596229781133EFD700DC4CBB /* GeolocationPositionCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 596229771133EFD700DC4CBB /* GeolocationPositionCache.cpp */; }; 1126 5962297A1133EFE200DC4CBB /* GeolocationPositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 596229791133EFE200DC4CBB /* GeolocationPositionCache.h */; };1126 5962297A1133EFE200DC4CBB /* GeolocationPositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 596229791133EFE200DC4CBB /* GeolocationPositionCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1127 1127 599E759011055A1F00D904FA /* Bridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 599E758F11055A1F00D904FA /* Bridge.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1128 1128 59A9E7B01104758800DFB4C1 /* JavaInstanceJSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59A9E7AF1104758800DFB4C1 /* JavaInstanceJSC.cpp */; }; -
trunk/WebCore/page/Geolocation.cpp
r55136 r55841 2 2 * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. 3 3 * Copyright (C) 2009 Torch Mobile, Inc. 4 * Copyright 2010, The Android Open Source Project 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 32 33 #include "Frame.h" 33 34 #include "Page.h" 35 #include <wtf/CurrentTime.h> 34 36 35 37 #if ENABLE(CLIENT_BASED_GEOLOCATION) … … 44 46 45 47 static const char permissionDeniedErrorMessage[] = "User denied Geolocation"; 48 static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocation service"; 46 49 47 50 #if ENABLE(CLIENT_BASED_GEOLOCATION) … … 80 83 , m_options(options) 81 84 , m_timer(this, &Geolocation::GeoNotifier::timerFired) 85 , m_useCachedPosition(false) 82 86 { 83 87 ASSERT(m_geolocation); … … 96 100 } 97 101 102 void Geolocation::GeoNotifier::setUseCachedPosition() 103 { 104 m_useCachedPosition = true; 105 m_timer.startOneShot(0); 106 } 107 98 108 bool Geolocation::GeoNotifier::hasZeroTimeout() const 99 109 { 100 110 return m_options->hasTimeout() && m_options->timeout() == 0; 111 } 112 113 void Geolocation::GeoNotifier::runSuccessCallback(Geoposition* position) 114 { 115 m_successCallback->handleEvent(position); 101 116 } 102 117 … … 123 138 } 124 139 140 if (m_useCachedPosition) { 141 // Clear the cached position flag in case this is a watch request, which 142 // will continue to run. 143 m_useCachedPosition = false; 144 m_geolocation->requestUsesCachedPosition(this); 145 return; 146 } 147 125 148 if (m_errorCallback) { 126 149 RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired"); … … 154 177 m_idToNotifierMap.remove(iter->second); 155 178 m_notifierToIdMap.remove(iter); 179 } 180 181 bool Geolocation::Watchers::contains(GeoNotifier* notifier) const 182 { 183 return m_notifierToIdMap.contains(notifier); 156 184 } 157 185 … … 179 207 , m_allowGeolocation(Unknown) 180 208 , m_shouldClearCache(false) 209 , m_positionCache(new GeolocationPositionCache) 181 210 { 182 211 if (!m_frame) … … 249 278 if (isDenied()) 250 279 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 251 else { 252 if (notifier->hasZeroTimeout() || startUpdating(notifier.get())) { 253 #if ENABLE(CLIENT_BASED_GEOLOCATION) 254 // Only start timer if we're not waiting for user permission. 255 if (!m_startRequestPermissionNotifier) 280 else if (haveSuitableCachedPosition(notifier->m_options.get())) 281 notifier->setUseCachedPosition(); 282 else if (notifier->hasZeroTimeout() || startUpdating(notifier.get())) { 283 #if ENABLE(CLIENT_BASED_GEOLOCATION) 284 // Only start timer if we're not waiting for user permission. 285 if (!m_startRequestPermissionNotifier) 256 286 #endif 257 notifier->startTimerIfNeeded(); 258 } else 259 notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, "Failed to start Geolocation service")); 260 } 287 notifier->startTimerIfNeeded(); 288 } else 289 notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 261 290 262 291 return notifier.release(); … … 273 302 } 274 303 304 void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier) 305 { 306 // This is called asynchronously, so the permissions could have been denied 307 // since we last checked in startRequest. 308 if (isDenied()) { 309 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); 310 return; 311 } 312 313 m_requestsAwaitingCachedPosition.add(notifier); 314 315 // If permissions are allowed, make the callback 316 if (isAllowed()) { 317 makeCachedPositionCallbacks(); 318 return; 319 } 320 321 // Request permissions, which may be synchronous or asynchronous. 322 requestPermission(); 323 } 324 325 void Geolocation::makeCachedPositionCallbacks() 326 { 327 // All modifications to m_requestsAwaitingCachedPosition are done 328 // asynchronously, so we don't need to worry about it being modified from 329 // the callbacks. 330 GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end(); 331 for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) { 332 GeoNotifier* notifier = iter->get(); 333 notifier->runSuccessCallback(m_positionCache->cachedPosition()); 334 335 // If this is a one-shot request, stop it. Otherwise, if the watch still 336 // exists, start the service to get updates. 337 if (m_oneShots.contains(notifier)) 338 m_oneShots.remove(notifier); 339 else if (m_watchers.contains(notifier)) { 340 if (notifier->hasZeroTimeout() || startUpdating(notifier)) 341 notifier->startTimerIfNeeded(); 342 else 343 notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 344 } 345 } 346 347 m_requestsAwaitingCachedPosition.clear(); 348 349 if (!hasListeners()) 350 stopUpdating(); 351 } 352 275 353 void Geolocation::requestTimedOut(GeoNotifier* notifier) 276 354 { … … 280 358 if (!hasListeners()) 281 359 stopUpdating(); 360 } 361 362 bool Geolocation::haveSuitableCachedPosition(PositionOptions* options) 363 { 364 if (!m_positionCache->cachedPosition()) 365 return false; 366 if (!options->hasMaximumAge()) 367 return true; 368 if (!options->maximumAge()) 369 return false; 370 DOMTimeStamp currentTimeMillis = currentTime() * 1000.0; 371 return m_positionCache->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge(); 282 372 } 283 373 … … 308 398 void Geolocation::setIsAllowed(bool allowed) 309 399 { 400 // This may be due to either a new position from the service, or a cached 401 // position. 310 402 m_allowGeolocation = allowed ? Yes : No; 311 403 … … 330 422 } 331 423 #endif 332 333 if (isAllowed()) 334 makeSuccessCallbacks(); 335 else { 424 425 if (!isAllowed()) { 336 426 RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage); 337 427 error->setIsFatal(true); 338 428 handleError(error.get()); 339 } 429 m_requestsAwaitingCachedPosition.clear(); 430 return; 431 } 432 433 // If the service has a last position, use it to call back for all requests. 434 // If any of the requests are waiting for permission for a cached position, 435 // the position from the service will be at least as fresh. 436 if (lastPosition()) 437 makeSuccessCallbacks(); 438 else 439 makeCachedPositionCallbacks(); 340 440 } 341 441 … … 439 539 m_currentPosition = newPosition; 440 540 541 m_positionCache->setCachedPosition(m_currentPosition.get()); 542 441 543 // Stop all currently running timers. 442 544 stopTimers(); … … 504 606 ASSERT(service->lastError()); 505 607 608 // Note that we do not stop timers here. For one-shots, the request is 609 // cleared in handleError. For watchers, the spec requires that the timer is 610 // not cleared. 506 611 handleError(service->lastError()); 507 612 } -
trunk/WebCore/page/Geolocation.h
r55633 r55841 1 1 /* 2 2 * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. 3 * Copyright 2010, The Android Open Source Project 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 27 28 #define Geolocation_h 28 29 30 #include "GeolocationPositionCache.h" 29 31 #include "GeolocationService.h" 30 32 #include "Geoposition.h" … … 96 98 void setFatalError(PassRefPtr<PositionError>); 97 99 bool hasZeroTimeout() const; 100 void setUseCachedPosition(); 101 void runSuccessCallback(Geoposition*); 98 102 void startTimerIfNeeded(); 99 103 void timerFired(Timer<GeoNotifier>*); … … 105 109 Timer<GeoNotifier> m_timer; 106 110 RefPtr<PositionError> m_fatalError; 111 bool m_useCachedPosition; 107 112 108 113 private: … … 115 120 void remove(int id); 116 121 void remove(GeoNotifier*); 122 bool contains(GeoNotifier*) const; 117 123 void clear(); 118 124 bool isEmpty() const; … … 154 160 void fatalErrorOccurred(GeoNotifier*); 155 161 void requestTimedOut(GeoNotifier*); 162 void requestUsesCachedPosition(GeoNotifier*); 163 bool haveSuitableCachedPosition(PositionOptions*); 164 void makeCachedPositionCallbacks(); 156 165 157 166 typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet; … … 175 184 } m_allowGeolocation; 176 185 bool m_shouldClearCache; 186 187 OwnPtr<GeolocationPositionCache> m_positionCache; 188 GeoNotifierSet m_requestsAwaitingCachedPosition; 177 189 }; 178 190
Note:
See TracChangeset
for help on using the changeset viewer.