diff options
author | Steve Block <steveblock@google.com> | 2010-01-26 08:33:05 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-01-26 08:33:05 -0800 |
commit | ab3eedd7e7e8a8ab78e3a507f85afcc6353461b0 (patch) | |
tree | e2253fcad018ce7b3b217fb46f78eb14e15833ce /WebCore/page | |
parent | d5ebf563d1a5ecc4473fc05753abec894087fedd (diff) | |
parent | 8a03f7cd9e884b3db11bb5485b4d9f5095dc0bca (diff) | |
download | external_webkit-ab3eedd7e7e8a8ab78e3a507f85afcc6353461b0.zip external_webkit-ab3eedd7e7e8a8ab78e3a507f85afcc6353461b0.tar.gz external_webkit-ab3eedd7e7e8a8ab78e3a507f85afcc6353461b0.tar.bz2 |
Merge "Moves the Geolocation position cache out of the Geolocation object."
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 |