summaryrefslogtreecommitdiffstats
path: root/WebCore/page/Geolocation.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-09-04 14:26:00 +0100
committerSteve Block <steveblock@google.com>2009-09-07 21:28:38 +0100
commitdfc37cc0448372eace961f14c698eedd4225c73a (patch)
treed08b3812456ed00a31f26073bd9fec23056023cf /WebCore/page/Geolocation.cpp
parentbc2cb6973923b5560298950bd824d9627d6ed765 (diff)
downloadexternal_webkit-dfc37cc0448372eace961f14c698eedd4225c73a.zip
external_webkit-dfc37cc0448372eace961f14c698eedd4225c73a.tar.gz
external_webkit-dfc37cc0448372eace961f14c698eedd4225c73a.tar.bz2
Store Geolocation cached position between browser sessions.
This fixes bug http://b/issue?id=2054431. Change-Id: I44b752b0c7fb4529027018c99dd945279b594b89
Diffstat (limited to 'WebCore/page/Geolocation.cpp')
-rw-r--r--WebCore/page/Geolocation.cpp120
1 files changed, 117 insertions, 3 deletions
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index adf5eb1..d7e0cc3 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -32,6 +32,10 @@
#include "Document.h"
#include "Frame.h"
#include "Page.h"
+#include "SQLiteDatabase.h"
+#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
+#include "SQLValue.h"
namespace WebCore {
@@ -96,17 +100,22 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
m_geolocation->requestTimedOut(this);
}
+static const char* databaseName = "/CachedPosition.db";
+
class CachedPositionManager {
public:
CachedPositionManager()
{
- if (s_instances++ == 0)
+ if (s_instances++ == 0) {
s_cachedPosition = new RefPtr<Geoposition>;
+ *s_cachedPosition = readFromDB();
+ }
}
~CachedPositionManager()
{
if (--s_instances == 0) {
- // TODO(steveblock): Store cached position between sessions.
+ if (*s_cachedPosition)
+ writeToDB(s_cachedPosition->get());
delete s_cachedPosition;
}
}
@@ -119,14 +128,114 @@ class CachedPositionManager {
{
return s_cachedPosition->get();
}
+ static void setDatabasePath(String databasePath)
+ {
+ 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:
+ private:
+ static PassRefPtr<Geoposition> readFromDB()
+ {
+ SQLiteDatabase database;
+ if (!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 (!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;
Geolocation::Geolocation(Frame* frame)
@@ -443,4 +552,9 @@ void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service)
handleError(service->lastError());
}
+void Geolocation::setDatabasePath(String databasePath)
+{
+ CachedPositionManager::setDatabasePath(databasePath);
+}
+
} // namespace WebCore