Adds cache to store Geolocation positions between browser sessions.
authorsteveblock@google.com <steveblock@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Feb 2010 12:07:45 +0000 (12:07 +0000)
committersteveblock@google.com <steveblock@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Feb 2010 12:07:45 +0000 (12:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=34084

Reviewed by Ariya Hidayat.

This is required to fully implement the Geolocation maximumAge property.
See Bug 30676.

No new tests, will add tests for maximumAge once complete.

* Android.mk: Modified. Added GeolocationPositionCache.cpp
* GNUmakefile.am: Modified. Added GeolocationPositionCache.[cpp|h]
* WebCore.gypi: Modified. Added GeolocationPositionCache.[cpp|h]
* WebCore.pro: Modified. Added GeolocationPositionCache.[cpp|h]
* WebCore.vcproj/WebCore.vcproj: Modified. Added GeolocationPositionCache.[cpp|h]
* WebCore.xcodeproj/project.pbxproj: Modified. Added GeolocationPositionCache.[cpp|h]
* page/GeolocationPositionCache.cpp: Added.
(WebCore::GeolocationPositionCache::GeolocationPositionCache):
(WebCore::GeolocationPositionCache::~GeolocationPositionCache):
(WebCore::GeolocationPositionCache::setCachedPosition):
(WebCore::GeolocationPositionCache::cachedPosition):
(WebCore::GeolocationPositionCache::setDatabasePath):
(WebCore::GeolocationPositionCache::readFromDB):
(WebCore::GeolocationPositionCache::writeToDB):
* page/GeolocationPositionCache.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@55142 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/Android.mk
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/page/GeolocationPositionCache.cpp [new file with mode: 0644]
WebCore/page/GeolocationPositionCache.h [new file with mode: 0644]

index bb991f3..c2411b1 100644 (file)
@@ -336,6 +336,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        page/FrameTree.cpp \
        page/FrameView.cpp \
        page/Geolocation.cpp \
+       page/GeolocationPositionCache.cpp \
        page/History.cpp \
        page/Location.cpp \
        page/MouseEventWithHitTestResults.cpp \
index a3586fd..b49f4bf 100644 (file)
@@ -1,3 +1,31 @@
+2010-02-17  Steve Block  <steveblock@google.com>
+
+        Reviewed by Ariya Hidayat.
+
+        Adds cache to store Geolocation positions between browser sessions.
+        https://bugs.webkit.org/show_bug.cgi?id=34084
+
+        This is required to fully implement the Geolocation maximumAge property.
+        See Bug 30676.
+
+        No new tests, will add tests for maximumAge once complete.
+
+        * Android.mk: Modified. Added GeolocationPositionCache.cpp
+        * GNUmakefile.am: Modified. Added GeolocationPositionCache.[cpp|h]
+        * WebCore.gypi: Modified. Added GeolocationPositionCache.[cpp|h]
+        * WebCore.pro: Modified. Added GeolocationPositionCache.[cpp|h]
+        * WebCore.vcproj/WebCore.vcproj: Modified. Added GeolocationPositionCache.[cpp|h]
+        * WebCore.xcodeproj/project.pbxproj: Modified. Added GeolocationPositionCache.[cpp|h]
+        * page/GeolocationPositionCache.cpp: Added.
+        (WebCore::GeolocationPositionCache::GeolocationPositionCache):
+        (WebCore::GeolocationPositionCache::~GeolocationPositionCache):
+        (WebCore::GeolocationPositionCache::setCachedPosition):
+        (WebCore::GeolocationPositionCache::cachedPosition):
+        (WebCore::GeolocationPositionCache::setDatabasePath):
+        (WebCore::GeolocationPositionCache::readFromDB):
+        (WebCore::GeolocationPositionCache::writeToDB):
+        * page/GeolocationPositionCache.h: Added.
+
 2010-02-23  Yuta Kitamura  <yutak@chromium.org>
 
         Reviewed by Dan Bernstein.
index 06f71d2..2975ffe 100644 (file)
@@ -1374,6 +1374,8 @@ webcore_sources += \
        WebCore/page/GeolocationControllerClient.h \
        WebCore/page/GeolocationError.h \
        WebCore/page/GeolocationPosition.h \
+       WebCore/page/GeolocationPositionCache.cpp \
+       WebCore/page/GeolocationPositionCache.h \
        WebCore/page/Geoposition.h \
        WebCore/page/HaltablePlugin.h \
        WebCore/page/History.cpp \
index f0bf518..8823fbf 100644 (file)
             'page/GeolocationControllerClient.h'
             'page/GeolocationError.h'
             'page/GeolocationPosition.h'
+            'page/GeolocationPositionCache.cpp'
+            'page/GeolocationPositionCache.h'
             'page/Geoposition.h',
             'page/HaltablePlugin.h',
             'page/History.cpp',
index fd8d45c..c625224 100644 (file)
@@ -759,6 +759,7 @@ SOURCES += \
     page/FrameView.cpp \
     page/Geolocation.cpp \
     page/GeolocationController.cpp \
+    page/GeolocationPositionCache.cpp \
     page/History.cpp \
     page/Location.cpp \
     page/MouseEventWithHitTestResults.cpp \
@@ -1457,6 +1458,7 @@ HEADERS += \
     page/FrameTree.h \
     page/FrameView.h \
     page/Geolocation.h \
+    page/GeolocationPositionCache.h \
     page/Geoposition.h \
     page/HaltablePlugin.h \
     page/History.h \
index 44ea351..8d6b557 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\page\GeolocationPositionCache.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\page\GeolocationPositionCache.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\page\GeolocationControllerClient.h"\r
                                >\r
                        </File>\r
index b89adc6..eaf9a5c 100644 (file)
                550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5913953B110758450083EC55 /* JNIBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 5913953A110758450083EC55 /* JNIBridge.h */; };
                5913953D1107584E0083EC55 /* JNIBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5913953C1107584E0083EC55 /* JNIBridge.cpp */; };
+               596229781133EFD700DC4CBB /* GeolocationPositionCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 596229771133EFD700DC4CBB /* GeolocationPositionCache.cpp */; };
+               5962297A1133EFE200DC4CBB /* GeolocationPositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 596229791133EFE200DC4CBB /* GeolocationPositionCache.h */; };
                599E759011055A1F00D904FA /* Bridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 599E758F11055A1F00D904FA /* Bridge.h */; settings = {ATTRIBUTES = (Private, ); }; };
                59A9E7B01104758800DFB4C1 /* JavaInstanceJSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59A9E7AF1104758800DFB4C1 /* JavaInstanceJSC.cpp */; };
                59A9E7B21104759400DFB4C1 /* JavaInstanceJSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 59A9E7B11104759400DFB4C1 /* JavaInstanceJSC.h */; };
                550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                5913953A110758450083EC55 /* JNIBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JNIBridge.h; sourceTree = "<group>"; };
                5913953C1107584E0083EC55 /* JNIBridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JNIBridge.cpp; sourceTree = "<group>"; };
+               596229771133EFD700DC4CBB /* GeolocationPositionCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeolocationPositionCache.cpp; sourceTree = "<group>"; };
+               596229791133EFE200DC4CBB /* GeolocationPositionCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeolocationPositionCache.h; sourceTree = "<group>"; };
                599E758F11055A1F00D904FA /* Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Bridge.h; path = bridge/Bridge.h; sourceTree = "<group>"; };
                59A9E7AF1104758800DFB4C1 /* JavaInstanceJSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaInstanceJSC.cpp; path = jsc/JavaInstanceJSC.cpp; sourceTree = "<group>"; };
                59A9E7B11104759400DFB4C1 /* JavaInstanceJSC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaInstanceJSC.h; path = jsc/JavaInstanceJSC.h; sourceTree = "<group>"; };
                65BF02180974806300C43196 /* page */ = {
                        isa = PBXGroup;
                        children = (
+                               596229791133EFE200DC4CBB /* GeolocationPositionCache.h */,
+                               596229771133EFD700DC4CBB /* GeolocationPositionCache.cpp */,
                                316FE1060E6E1D8400BF6088 /* animation */,
                                93C09A820B064F05005ABD4D /* mac */,
                                8538F0000AD71770006A81D1 /* AbstractView.idl */,
                                9F2A322E1125A0A2003C3056 /* JavaScriptProfileNode.h in Headers */,
                                7AFD4A8B1131C2760035B883 /* ScriptBreakpoint.h in Headers */,
                                7AFD4FF4113277B60035B883 /* ScriptDebugListener.h in Headers */,
+                               5962297A1133EFE200DC4CBB /* GeolocationPositionCache.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                9F2A322D1125A0A2003C3056 /* JavaScriptProfileNode.cpp in Sources */,
                                6E21C6C01126338500A7BE02 /* GraphicsContext3D.cpp in Sources */,
                                6E21C6C21126339900A7BE02 /* GraphicsContext3DCG.cpp in Sources */,
+                               596229781133EFD700DC4CBB /* GeolocationPositionCache.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/WebCore/page/GeolocationPositionCache.cpp b/WebCore/page/GeolocationPositionCache.cpp
new file mode 100644 (file)
index 0000000..5796191
--- /dev/null
@@ -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 "SQLiteFileSystem.h"
+#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
+
+
+namespace WebCore {
+
+static const char* databaseName = "CachedGeoposition.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)
+{
+    *s_cachedPosition = cachedPosition;
+}
+
+Geoposition* GeolocationPositionCache::cachedPosition()
+{
+    return s_cachedPosition->get();
+}
+
+void GeolocationPositionCache::setDatabasePath(const String& databasePath)
+{
+    if (!s_databaseFile)
+        s_databaseFile = new String;
+    *s_databaseFile = SQLiteFileSystem::appendDatabaseFileNameToPath(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(const 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 (file)
index 0000000..c7f7e49
--- /dev/null
@@ -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(const String&);
+
+  private:
+    static PassRefPtr<Geoposition> readFromDB();
+    static void writeToDB(const Geoposition*);
+
+    static int s_instances;
+    static RefPtr<Geoposition>* s_cachedPosition;
+    static String* s_databaseFile;
+};
+
+} // namespace WebCore
+
+#endif // GeolocationPositionCache_h