diff options
author | Steve Block <steveblock@google.com> | 2010-01-25 18:03:49 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-01-25 18:49:31 +0000 |
commit | 8a03f7cd9e884b3db11bb5485b4d9f5095dc0bca (patch) | |
tree | cfa1482c9769390fe06bfca99d85c0daabf6532d /WebCore/page | |
parent | f194ee8ea5e8e00930a6caddc3ef6f5031493c2b (diff) | |
download | external_webkit-8a03f7cd9e884b3db11bb5485b4d9f5095dc0bca.zip external_webkit-8a03f7cd9e884b3db11bb5485b4d9f5095dc0bca.tar.gz external_webkit-8a03f7cd9e884b3db11bb5485b4d9f5095dc0bca.tar.bz2 |
Moves the Geolocation position cache out of the Geolocation object.
The position cache is an implementation detail of the Geolocation object,
but is being moved to its own file to keep files to a reasonable size.
Also updates some names and fixes soem style.
This will be upstreamed in
https://bugs.webkit.org/show_bug.cgi?id=34084
The maximumAge code in the Geolocation object,
which may make use of this caching, is being upstreamed in
https://bugs.webkit.org/show_bug.cgi?id=30676
Change-Id: I083556de732bd7be240a75da5369117aabc50e33
Diffstat (limited to 'WebCore/page')
-rw-r--r-- | WebCore/page/Geolocation.cpp | 173 | ||||
-rw-r--r-- | WebCore/page/Geolocation.h | 7 | ||||
-rw-r--r-- | WebCore/page/GeolocationPositionCache.cpp | 175 | ||||
-rw-r--r-- | WebCore/page/GeolocationPositionCache.h | 58 |
4 files changed, 246 insertions, 167 deletions
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp index cc5cc93..0727973 100644 --- a/WebCore/page/Geolocation.cpp +++ b/WebCore/page/Geolocation.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. * Copyright (C) 2009 Torch Mobile, Inc. + * Copyright 2010, The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,15 +29,11 @@ #include "Geolocation.h" #include "Chrome.h" -#include "Document.h" #include "DOMWindow.h" +#include "Document.h" #include "EventNames.h" #include "Frame.h" #include "Page.h" -#include "SQLiteDatabase.h" -#include "SQLiteStatement.h" -#include "SQLiteTransaction.h" -#include "SQLValue.h" #include <wtf/CurrentTime.h> #if ENABLE(CLIENT_BASED_GEOLOCATION) @@ -196,146 +193,6 @@ void Geolocation::Watchers::getNotifiersVector(Vector<RefPtr<GeoNotifier> >& cop copyValuesToVector(m_idToNotifierMap, copy); } -static const char* databaseName = "/CachedPosition.db"; - -class CachedPositionManager { - public: - CachedPositionManager() - { - if (s_instances++ == 0) { - s_cachedPosition = new RefPtr<Geoposition>; - *s_cachedPosition = readFromDB(); - } - } - ~CachedPositionManager() - { - if (--s_instances == 0) { - if (*s_cachedPosition) - writeToDB(s_cachedPosition->get()); - delete s_cachedPosition; - } - } - void setCachedPosition(Geoposition* cachedPosition) - { - // We do not take owenership from the caller, but add our own ref count. - *s_cachedPosition = cachedPosition; - } - Geoposition* cachedPosition() - { - return s_cachedPosition->get(); - } - static void setDatabasePath(String databasePath) - { - if (!s_databaseFile) - s_databaseFile = new String; - *s_databaseFile = databasePath + databaseName; - // If we don't have have a cached position, attempt to read one from the - // DB at the new path. - if (s_instances && *s_cachedPosition == 0) - *s_cachedPosition = readFromDB(); - } - - private: - static PassRefPtr<Geoposition> readFromDB() - { - SQLiteDatabase database; - if (!s_databaseFile || !database.open(*s_databaseFile)) - return 0; - - // Create the table here, such that even if we've just created the - // DB, the commands below should succeed. - if (!database.executeCommand("CREATE TABLE IF NOT EXISTS CachedPosition (" - "latitude REAL NOT NULL, " - "longitude REAL NOT NULL, " - "altitude REAL, " - "accuracy REAL NOT NULL, " - "altitudeAccuracy REAL, " - "heading REAL, " - "speed REAL, " - "timestamp INTEGER NOT NULL)")) - return 0; - - SQLiteStatement statement(database, "SELECT * FROM CachedPosition"); - if (statement.prepare() != SQLResultOk) - return 0; - - if (statement.step() != SQLResultRow) - return 0; - - bool providesAltitude = statement.getColumnValue(2).type() != SQLValue::NullValue; - bool providesAltitudeAccuracy = statement.getColumnValue(4).type() != SQLValue::NullValue; - bool providesHeading = statement.getColumnValue(5).type() != SQLValue::NullValue; - bool providesSpeed = statement.getColumnValue(6).type() != SQLValue::NullValue; - RefPtr<Coordinates> coordinates = Coordinates::create(statement.getColumnDouble(0), // latitude - statement.getColumnDouble(1), // longitude - providesAltitude, statement.getColumnDouble(2), // altitude - statement.getColumnDouble(3), // accuracy - providesAltitudeAccuracy, statement.getColumnDouble(4), // altitudeAccuracy - providesHeading, statement.getColumnDouble(5), // heading - providesSpeed, statement.getColumnDouble(6)); // speed - return Geoposition::create(coordinates.release(), statement.getColumnInt64(7)); // timestamp - } - static void writeToDB(Geoposition* position) - { - ASSERT(position); - - SQLiteDatabase database; - if (!s_databaseFile || !database.open(*s_databaseFile)) - return; - - SQLiteTransaction transaction(database); - - if (!database.executeCommand("DELETE FROM CachedPosition")) - return; - - SQLiteStatement statement(database, "INSERT INTO CachedPosition (" - "latitude, " - "longitude, " - "altitude, " - "accuracy, " - "altitudeAccuracy, " - "heading, " - "speed, " - "timestamp) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - if (statement.prepare() != SQLResultOk) - return; - - statement.bindDouble(1, position->coords()->latitude()); - statement.bindDouble(2, position->coords()->longitude()); - if (position->coords()->canProvideAltitude()) - statement.bindDouble(3, position->coords()->altitude()); - else - statement.bindNull(3); - statement.bindDouble(4, position->coords()->accuracy()); - if (position->coords()->canProvideAltitudeAccuracy()) - statement.bindDouble(5, position->coords()->altitudeAccuracy()); - else - statement.bindNull(5); - if (position->coords()->canProvideHeading()) - statement.bindDouble(6, position->coords()->heading()); - else - statement.bindNull(6); - if (position->coords()->canProvideSpeed()) - statement.bindDouble(7, position->coords()->speed()); - else - statement.bindNull(7); - statement.bindInt64(8, position->timestamp()); - if (!statement.executeCommand()) - return; - - transaction.commit(); - } - static int s_instances; - static RefPtr<Geoposition>* s_cachedPosition; - static String* s_databaseFile; -}; - -int CachedPositionManager::s_instances = 0; -RefPtr<Geoposition>* CachedPositionManager::s_cachedPosition; -String* CachedPositionManager::s_databaseFile = 0; - - Geolocation::Geolocation(Frame* frame) : EventListener(GeolocationEventListenerType) , m_frame(frame) @@ -344,7 +201,7 @@ Geolocation::Geolocation(Frame* frame) #endif , m_allowGeolocation(Unknown) , m_shouldClearCache(false) - , m_cachedPositionManager(new CachedPositionManager) + , m_positionCache(new GeolocationPositionCache) { if (!m_frame) return; @@ -367,8 +224,6 @@ void Geolocation::disconnectFrame() if (m_frame && m_frame->document()) m_frame->document()->setUsingGeolocation(false); m_frame = 0; - - delete m_cachedPositionManager; } Geoposition* Geolocation::lastPosition() @@ -420,9 +275,8 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); else { if (haveSuitableCachedPosition(notifier->m_options.get())) { - ASSERT(m_cachedPositionManager->cachedPosition()); if (isAllowed()) - notifier->setCachedPosition(m_cachedPositionManager->cachedPosition()); + notifier->setCachedPosition(m_positionCache->cachedPosition()); else { m_requestsAwaitingCachedPosition.add(notifier); requestPermission(); @@ -475,14 +329,14 @@ void Geolocation::requestReturnedCachedPosition(GeoNotifier* notifier) bool Geolocation::haveSuitableCachedPosition(PositionOptions* options) { - if (m_cachedPositionManager->cachedPosition() == 0) + if (!m_positionCache->cachedPosition()) return false; if (!options->hasMaximumAge()) return true; if (options->maximumAge() == 0) return false; DOMTimeStamp currentTimeMillis = currentTime() * 1000.0; - return m_cachedPositionManager->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge(); + return m_positionCache->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge(); } void Geolocation::clearWatch(int watchId) @@ -525,14 +379,12 @@ void Geolocation::setIsAllowed(bool allowed) // If the service has a last position, use it to call back for all requests. // If any of the requests are waiting for permission for a cached position, // the position from the service will be at least as fresh. - if (m_service->lastPosition()) + if (lastPosition()) makeSuccessCallbacks(); else { GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end(); - for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) { - ASSERT(m_cachedPositionManager->cachedPosition()); - (*iter)->setCachedPosition(m_cachedPositionManager->cachedPosition()); - } + for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) + (*iter)->setCachedPosition(m_positionCache->cachedPosition()); } m_requestsAwaitingCachedPosition.clear(); } @@ -636,7 +488,7 @@ void Geolocation::positionChanged(PassRefPtr<Geoposition> newPosition) { m_currentPosition = newPosition; - m_cachedPositionManager->setCachedPosition(m_currentPosition.get()); + m_positionCache->setCachedPosition(m_currentPosition.get()); // Stop all currently running timers. stopTimers(); @@ -766,9 +618,4 @@ void Geolocation::handleEvent(ScriptExecutionContext*, Event* event) m_watchers.clear(); } -void Geolocation::setDatabasePath(String databasePath) -{ - CachedPositionManager::setDatabasePath(databasePath); -} - } // namespace WebCore diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h index 3006b29..808ee9c 100644 --- a/WebCore/page/Geolocation.h +++ b/WebCore/page/Geolocation.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. + * Copyright 2010, The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,6 +28,7 @@ #define Geolocation_h #include "EventListener.h" +#include "GeolocationPositionCache.h" #include "GeolocationService.h" #include "Geoposition.h" #include "PositionCallback.h" @@ -46,7 +48,6 @@ namespace WebCore { class Frame; -class CachedPositionManager; #if ENABLE(CLIENT_BASED_GEOLOCATION) class GeolocationPosition; @@ -86,8 +87,6 @@ public: void setError(GeolocationError*); #endif - static void setDatabasePath(String); - private: Geolocation(Frame*); @@ -184,7 +183,7 @@ private: } m_allowGeolocation; bool m_shouldClearCache; - CachedPositionManager* m_cachedPositionManager; + OwnPtr<GeolocationPositionCache> m_positionCache; GeoNotifierSet m_requestsAwaitingCachedPosition; }; diff --git a/WebCore/page/GeolocationPositionCache.cpp b/WebCore/page/GeolocationPositionCache.cpp new file mode 100644 index 0000000..7bc361a --- /dev/null +++ b/WebCore/page/GeolocationPositionCache.cpp @@ -0,0 +1,175 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GeolocationPositionCache.h" + +#include "Geoposition.h" +#include "SQLValue.h" +#include "SQLiteDatabase.h" +#include "SQLiteStatement.h" +#include "SQLiteTransaction.h" + + +namespace WebCore { + +static const char* databaseName = "/CachedPosition.db"; + +int GeolocationPositionCache::s_instances = 0; +RefPtr<Geoposition>* GeolocationPositionCache::s_cachedPosition; +String* GeolocationPositionCache::s_databaseFile = 0; + +GeolocationPositionCache::GeolocationPositionCache() +{ + if (!(s_instances++)) { + s_cachedPosition = new RefPtr<Geoposition>; + *s_cachedPosition = readFromDB(); + } +} + +GeolocationPositionCache::~GeolocationPositionCache() +{ + if (!(--s_instances)) { + if (*s_cachedPosition) + writeToDB(s_cachedPosition->get()); + delete s_cachedPosition; + } +} + +void GeolocationPositionCache::setCachedPosition(Geoposition* cachedPosition) +{ + // We do not take owenership from the caller, but add our own ref count. + *s_cachedPosition = cachedPosition; +} + +Geoposition* GeolocationPositionCache::cachedPosition() +{ + return s_cachedPosition->get(); +} + +void GeolocationPositionCache::setDatabasePath(String databasePath) +{ + if (!s_databaseFile) + s_databaseFile = new String; + *s_databaseFile = databasePath + databaseName; + // If we don't have have a cached position, attempt to read one from the + // DB at the new path. + if (s_instances && !(*s_cachedPosition)) + *s_cachedPosition = readFromDB(); +} + +PassRefPtr<Geoposition> GeolocationPositionCache::readFromDB() +{ + SQLiteDatabase database; + if (!s_databaseFile || !database.open(*s_databaseFile)) + return 0; + + // Create the table here, such that even if we've just created the + // DB, the commands below should succeed. + if (!database.executeCommand("CREATE TABLE IF NOT EXISTS CachedPosition (" + "latitude REAL NOT NULL, " + "longitude REAL NOT NULL, " + "altitude REAL, " + "accuracy REAL NOT NULL, " + "altitudeAccuracy REAL, " + "heading REAL, " + "speed REAL, " + "timestamp INTEGER NOT NULL)")) + return 0; + + SQLiteStatement statement(database, "SELECT * FROM CachedPosition"); + if (statement.prepare() != SQLResultOk) + return 0; + + if (statement.step() != SQLResultRow) + return 0; + + bool providesAltitude = statement.getColumnValue(2).type() != SQLValue::NullValue; + bool providesAltitudeAccuracy = statement.getColumnValue(4).type() != SQLValue::NullValue; + bool providesHeading = statement.getColumnValue(5).type() != SQLValue::NullValue; + bool providesSpeed = statement.getColumnValue(6).type() != SQLValue::NullValue; + RefPtr<Coordinates> coordinates = Coordinates::create(statement.getColumnDouble(0), // latitude + statement.getColumnDouble(1), // longitude + providesAltitude, statement.getColumnDouble(2), // altitude + statement.getColumnDouble(3), // accuracy + providesAltitudeAccuracy, statement.getColumnDouble(4), // altitudeAccuracy + providesHeading, statement.getColumnDouble(5), // heading + providesSpeed, statement.getColumnDouble(6)); // speed + return Geoposition::create(coordinates.release(), statement.getColumnInt64(7)); // timestamp +} + +void GeolocationPositionCache::writeToDB(Geoposition* position) +{ + ASSERT(position); + + SQLiteDatabase database; + if (!s_databaseFile || !database.open(*s_databaseFile)) + return; + + SQLiteTransaction transaction(database); + + if (!database.executeCommand("DELETE FROM CachedPosition")) + return; + + SQLiteStatement statement(database, "INSERT INTO CachedPosition (" + "latitude, " + "longitude, " + "altitude, " + "accuracy, " + "altitudeAccuracy, " + "heading, " + "speed, " + "timestamp) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + if (statement.prepare() != SQLResultOk) + return; + + statement.bindDouble(1, position->coords()->latitude()); + statement.bindDouble(2, position->coords()->longitude()); + if (position->coords()->canProvideAltitude()) + statement.bindDouble(3, position->coords()->altitude()); + else + statement.bindNull(3); + statement.bindDouble(4, position->coords()->accuracy()); + if (position->coords()->canProvideAltitudeAccuracy()) + statement.bindDouble(5, position->coords()->altitudeAccuracy()); + else + statement.bindNull(5); + if (position->coords()->canProvideHeading()) + statement.bindDouble(6, position->coords()->heading()); + else + statement.bindNull(6); + if (position->coords()->canProvideSpeed()) + statement.bindDouble(7, position->coords()->speed()); + else + statement.bindNull(7); + statement.bindInt64(8, position->timestamp()); + if (!statement.executeCommand()) + return; + + transaction.commit(); +} + +} // namespace WebCore diff --git a/WebCore/page/GeolocationPositionCache.h b/WebCore/page/GeolocationPositionCache.h new file mode 100644 index 0000000..2dcfc57 --- /dev/null +++ b/WebCore/page/GeolocationPositionCache.h @@ -0,0 +1,58 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GeolocationPositionCache_h +#define GeolocationPositionCache_h + +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + + +namespace WebCore { + +class Geoposition; +class String; + +class GeolocationPositionCache { + public: + GeolocationPositionCache(); + ~GeolocationPositionCache(); + + void setCachedPosition(Geoposition*); + Geoposition* cachedPosition(); + static void setDatabasePath(String); + + private: + static PassRefPtr<Geoposition> readFromDB(); + static void writeToDB(Geoposition*); + + static int s_instances; + static RefPtr<Geoposition>* s_cachedPosition; + static String* s_databaseFile; +}; + +} // namespace WebCore + +#endif // GeolocationPositionCache_h |