2009-09-07  Steve Block  <steveblock@google.com>

        Reviewed by Adam Barth.

        Adds a mock Geolocation service. This will be used to provide predictable behavior of the
        Geolocation API for use in LayoutTests. Later changes will integrate the the mock
        Geolocation service with DumpRenderTree.
        https://bugs.webkit.org/show_bug.cgi?id=28264

        * fast/dom/Geolocation/resources/error.js: Added. Tests that the error callback is called when the service reports an error.
        * fast/dom/Geolocation/error-expected.txt: Added. Expected result for above test.
        * fast/dom/Geolocation/error.html: Added. Wrapper for above test.
2009-09-07  Steve Block  <steveblock@google.com>

        Reviewed by Adam Barth.

        Adds a mock Geolocation service. This will be used to provide predictable behavior of the
        Geolocation API for use in LayoutTests. Later changes will integrate the the mock
        Geolocation service with DumpRenderTree.
        https://bugs.webkit.org/show_bug.cgi?id=28264

        The mock Geolocation service returns a fixed position or error. This position or error can be
        set through static methods on the GeolocationService class. The position or error is shared
        between all instances of the mock Geolocation service.

        Implementation details.
        The GeolocationService object maintains a pointer to a factory function which it uses to create
        Geolocation service instances. Each platform implementing Geolocation sets this pointer
        to the factory function for their platform's implementation. When the mock Geolocation service
        is activated, the factory function pointer is reset to the factory function for the mock service.

        Test: fast/dom/Geolocation/error.html

        * WebCore.base.exp: Modified. Exports GeolocationServiceMock methods.
        * GNUMakefile.am: Modified. Added GeolocationServiceMock files.
        * WebCore.gypi: Modified. Added GeolocationServiceMock files.
        * WebCore.pro: Modified. Added GeolocationServiceMock files.
        * WebCore.vcproj/WebCore.vcproj: Modified. Added GeolocationServiceMock files.
        * WebCore.vcproj/WebCoreCommon.vsprops: Modified. Added mock directory to includes.
        * WebCore.xcodeproj/project.pbxproj: Modified. Added GeolocationServiceMock files and exports some headers.
        * WebCoreSources.bkl: Modified. Added GeolocationServiceMock files.
        * page/ChromeClient.h: Modified. Fixed comment.
        * page/Geolocation.cpp: Modified.
        (WebCore::Geolocation::setIsAllowed): Modified. Fixed error string.
        * platform/GeolocationService.cpp: Modified.
        (WebCore::createGeolocationServiceNull): Added. Returns null in place of a Geolocation service. Used to avoid link errors on platforms where Geolocation is not implemented.
        (WebCore::GeolocationService::create): Added. Uses the factory function pointer to create a Geolocation service implementation.
        (WebCore::GeolocationService::useMock): Added. Configures the GeolocationServie to use the mock implementation.
        * platform/GeolocationService.h: Modified.
        * platform/mock: Added.
        * platform/mock/GeolocationServiceMock.cpp: Added.
        (WebCore::GeolocationServiceMock::create): Added. Creates a GeolocationServiceMock object.
        (WebCore::GeolocationServiceMock::GeolocationServiceMock): Added. Constructor.
        (WebCore::GeolocationServiceMock::~GeolocationServiceMock): Added. Destructor.
        (WebCore::GeolocationServiceMock::setPosition): Added. Sets the position that will be returned by the object.
        (WebCore::GeolocationServiceMock::setError): Added. Sets the error that will be returned by the object.
        (WebCore::GeolocationServiceMock::startUpdating): Added. GeolocationService implementation. Starts the service.
        (WebCore::GeolocationServiceMock::stopUpdating): Added. GeolocationService implementation. Stops the service.
        (WebCore::GeolocationServiceMock::timerFired): Added. Used to provide an asynchronous callback when the service is started.
        (WebCore::GeolocationServiceMock::makeGeolocationCallbackFromAllInstances): Added. Used to call back when the position or error is updated.
        (WebCore::GeolocationServiceMock::makeGeolocationCallback): Added. Used to call back when the service starts.
        (WebCore::GeolocationServiceMock::initStatics): Added. Initializes statics members with constructors.
        (WebCore::GeolocationServiceMock::cleanUpStatics): Added. Cleans up static members with constructors.
        * platform/mock/GeolocationServiceMock.h: Added.
        (WebCore::GeolocationServiceMock::lastPosition): Added. Returns the fixed position.
        (WebCore::GeolocationServiceMock::lastError): Added. Returns the fixed error.
        * platform/gtk/GeolocationServiceGtk.cpp: Modified.
        (WebCore::GeolocationServiceGtk::create): Added. Creates an instance of GeolocationServiceGtk.
        * platform/gtk/GeolocationServiceGtk.h: Modified.
        * platform/mac/GeolocationServiceMac.h: Modified.
        * platform/mac/GeolocationServiceMac.mm: Modified.
        (WebCore::GeolocationServiceMac::create): Added. Creates an instance of GeolocationServiceMac.
2009-09-07  Steve Block  <steveblock@google.com>

        Reviewed by Adam Barth.

        Adds a mock Geolocation service. This will be used to provide predictable behavior of the
        Geolocation API for use in LayoutTests. Later changes will integrate the the mock
        Geolocation service with DumpRenderTree.
        https://bugs.webkit.org/show_bug.cgi?id=28264

        * WebKit.xcodeproj/project.pbxproj: Modified. Adds WebGeolocationMock.
2009-09-07  Steve Block  <steveblock@google.com>

        Reviewed by Adam Barth.

        Adds a mock Geolocation service. This will be used to provide predictable behavior of the
        Geolocation API for use in LayoutTests. Later changes will integrate the the mock
        Geolocation service with DumpRenderTree.
        https://bugs.webkit.org/show_bug.cgi?id=28264

        * WebCoreSupport/WebGeolocationMockPrivate.h: Added.
        * WebCoreSupport/WebGeolocationMock.mm: Added.
        (+[WebGeolocationMock setError:code:]): Added. Used by DumpRender tree to configure the mock Geolocation service.
        (+[WebGeolocationMock setPosition:latitude:longitude:accuracy:]): Added. Used by DumpRender tree to configure the mock Geolocation service.
        * WebKit.exp: Modified. Exports WebGeolocationMock.
2009-09-07  Steve Block  <steveblock@google.com>

        Reviewed by Adam Barth.

        Adds a mock Geolocation service. This will be used to provide predictable behavior of the
        Geolocation API for use in LayoutTests. Later changes will integrate the the mock
        Geolocation service with DumpRenderTree.
        https://bugs.webkit.org/show_bug.cgi?id=28264

        * DumpRenderTree/LayoutTestController.cpp: Modified.
        (setMockGeolocationPositionCallback): Added. Configures the mock Geolocation service.
        (setMockGeolocationErrorCallback): Added. Configures the mock Geolocation service.
        (LayoutTestController::staticFunctions): Added. Registers the above functions on the LayoutTestController.
        * DumpRenderTree/LayoutTestController.h: Modified.
        * DumpRenderTree/mac/LayoutTestControllerMac.mm: Modified.
        (LayoutTestController::setMockGeolocationPosition): Added. Configures the mock Geolocation service.
        (LayoutTestController::setMockGeolocationError): Added. Configures the mock Geolocation service.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48144 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d15bbc4..ccdb8e4 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,64 @@
+2009-09-07  Steve Block  <steveblock@google.com>
+
+        Reviewed by Adam Barth.
+
+        Adds a mock Geolocation service. This will be used to provide predictable behavior of the
+        Geolocation API for use in LayoutTests. Later changes will integrate the the mock
+        Geolocation service with DumpRenderTree.
+        https://bugs.webkit.org/show_bug.cgi?id=28264
+
+        The mock Geolocation service returns a fixed position or error. This position or error can be
+        set through static methods on the GeolocationService class. The position or error is shared
+        between all instances of the mock Geolocation service.
+
+        Implementation details.
+        The GeolocationService object maintains a pointer to a factory function which it uses to create
+        Geolocation service instances. Each platform implementing Geolocation sets this pointer
+        to the factory function for their platform's implementation. When the mock Geolocation service
+        is activated, the factory function pointer is reset to the factory function for the mock service.
+
+        Test: fast/dom/Geolocation/error.html
+
+        * WebCore.base.exp: Modified. Exports GeolocationServiceMock methods.
+        * GNUMakefile.am: Modified. Added GeolocationServiceMock files.
+        * WebCore.gypi: Modified. Added GeolocationServiceMock files.
+        * WebCore.pro: Modified. Added GeolocationServiceMock files.
+        * WebCore.vcproj/WebCore.vcproj: Modified. Added GeolocationServiceMock files.
+        * WebCore.vcproj/WebCoreCommon.vsprops: Modified. Added mock directory to includes.
+        * WebCore.xcodeproj/project.pbxproj: Modified. Added GeolocationServiceMock files and exports some headers.
+        * WebCoreSources.bkl: Modified. Added GeolocationServiceMock files.
+        * page/ChromeClient.h: Modified. Fixed comment.
+        * page/Geolocation.cpp: Modified.
+        (WebCore::Geolocation::setIsAllowed): Modified. Fixed error string.
+        * platform/GeolocationService.cpp: Modified.
+        (WebCore::createGeolocationServiceNull): Added. Returns null in place of a Geolocation service. Used to avoid link errors on platforms where Geolocation is not implemented.
+        (WebCore::GeolocationService::create): Added. Uses the factory function pointer to create a Geolocation service implementation.
+        (WebCore::GeolocationService::useMock): Added. Configures the GeolocationServie to use the mock implementation.
+        * platform/GeolocationService.h: Modified.
+        * platform/mock: Added.
+        * platform/mock/GeolocationServiceMock.cpp: Added.
+        (WebCore::GeolocationServiceMock::create): Added. Creates a GeolocationServiceMock object.
+        (WebCore::GeolocationServiceMock::GeolocationServiceMock): Added. Constructor.
+        (WebCore::GeolocationServiceMock::~GeolocationServiceMock): Added. Destructor.
+        (WebCore::GeolocationServiceMock::setPosition): Added. Sets the position that will be returned by the object.
+        (WebCore::GeolocationServiceMock::setError): Added. Sets the error that will be returned by the object.
+        (WebCore::GeolocationServiceMock::startUpdating): Added. GeolocationService implementation. Starts the service.
+        (WebCore::GeolocationServiceMock::stopUpdating): Added. GeolocationService implementation. Stops the service.
+        (WebCore::GeolocationServiceMock::timerFired): Added. Used to provide an asynchronous callback when the service is started.
+        (WebCore::GeolocationServiceMock::makeGeolocationCallbackFromAllInstances): Added. Used to call back when the position or error is updated.
+        (WebCore::GeolocationServiceMock::makeGeolocationCallback): Added. Used to call back when the service starts.
+        (WebCore::GeolocationServiceMock::initStatics): Added. Initializes statics members with constructors.
+        (WebCore::GeolocationServiceMock::cleanUpStatics): Added. Cleans up static members with constructors.
+        * platform/mock/GeolocationServiceMock.h: Added.
+        (WebCore::GeolocationServiceMock::lastPosition): Added. Returns the fixed position.
+        (WebCore::GeolocationServiceMock::lastError): Added. Returns the fixed error.
+        * platform/gtk/GeolocationServiceGtk.cpp: Modified.
+        (WebCore::GeolocationServiceGtk::create): Added. Creates an instance of GeolocationServiceGtk.
+        * platform/gtk/GeolocationServiceGtk.h: Modified.
+        * platform/mac/GeolocationServiceMac.h: Modified.
+        * platform/mac/GeolocationServiceMac.mm: Modified.
+        (WebCore::GeolocationServiceMac::create): Added. Creates an instance of GeolocationServiceMac.
+
 2009-09-07  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Dimitri Glazkov.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 873e06b..3d520bd8 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -41,6 +41,7 @@
 	-I$(srcdir)/WebCore/platform/image-decoders/jpeg \
 	-I$(srcdir)/WebCore/platform/image-decoders/png \
 	-I$(srcdir)/WebCore/platform/image-decoders/xbm \
+	-I$(srcdir)/WebCore/platform/mock \
 	-I$(srcdir)/WebCore/platform/network \
 	-I$(srcdir)/WebCore/platform/text \
 	-I$(srcdir)/WebCore/plugins \
@@ -1395,6 +1396,8 @@
 	WebCore/platform/Logging.h \
 	WebCore/platform/MIMETypeRegistry.cpp \
 	WebCore/platform/MIMETypeRegistry.h \
+	WebCore/platform/mock/GeolocationServiceMock.cpp \
+	WebCore/platform/mock/GeolocationServiceMock.h \
 	WebCore/platform/NotImplemented.h \
 	WebCore/platform/Pasteboard.h \
 	WebCore/platform/PlatformKeyboardEvent.h \
diff --git a/WebCore/WebCore.base.exp b/WebCore/WebCore.base.exp
index b616d56..1a0e5b2 100644
--- a/WebCore/WebCore.base.exp
+++ b/WebCore/WebCore.base.exp
@@ -442,6 +442,8 @@
 __ZN7WebCore21findEventWithKeyStateEPNS_5EventE
 __ZN7WebCore21isBackForwardLoadTypeENS_13FrameLoadTypeE
 __ZN7WebCore21reportThreadViolationEPKcNS_20ThreadViolationRoundE
+__ZN7WebCore22GeolocationServiceMock11setPositionEN3WTF10PassRefPtrINS_11GeopositionEEE
+__ZN7WebCore22GeolocationServiceMock8setErrorEN3WTF10PassRefPtrINS_13PositionErrorEEE
 __ZN7WebCore22ScriptExecutionContext26canSuspendActiveDOMObjectsEv
 __ZN7WebCore22applicationIsAppleMailEv
 __ZN7WebCore22createFragmentFromTextEPNS_5RangeERKNS_6StringE
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 6bc5717..69b1d70 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -2607,6 +2607,8 @@
             'platform/Logging.h',
             'platform/MIMETypeRegistry.cpp',
             'platform/MIMETypeRegistry.h',
+            'platform/mock/GeolocationServiceMock.cpp',
+            'platform/mock/GeolocationServiceMock.h',
             'platform/NotImplemented.h',
             'platform/Pasteboard.h',
             'platform/PlatformKeyboardEvent.h',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 7159b5f..3abc4ec 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -212,6 +212,7 @@
     $$PWD/platform/graphics/filters \
     $$PWD/platform/graphics/transforms \
     $$PWD/platform/image-decoders \
+    $$PWD/platform/mock \
     $$PWD/platform/network \
     $$PWD/platform/sql \
     $$PWD/platform/text \
@@ -1188,6 +1189,7 @@
     platform/LinkHash.cpp \
     platform/Logging.cpp \
     platform/MIMETypeRegistry.cpp \
+    platform/mock/GeolocationServiceMock.cpp \
     platform/network/AuthenticationChallengeBase.cpp \
     platform/network/Credential.cpp \
     platform/network/FormData.cpp \
@@ -1819,6 +1821,7 @@
     platform/DragImage.h \
     platform/FileChooser.h \
     platform/GeolocationService.h \
+    platform/mock/GeolocationServiceMock.h \
     platform/graphics/BitmapImage.h \
     platform/graphics/Color.h \
     platform/graphics/filters/FEBlend.h \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 5d11c39..6117734 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -17068,11 +17068,11 @@
 				RelativePath="..\page\Settings.h"

 				>

 			</File>

-                        <File

+      <File

 				RelativePath="..\page\UserScript.h"

 				>

 			</File>

-                        <File

+      <File

 				RelativePath="..\page\UserScriptTypes.h"

 				>

 			</File>

@@ -21759,6 +21759,18 @@
 					>

 				</File>

 			</Filter>

+ 			<Filter

+ 				Name="mock"

+ 				>

+ 				<File

+ 					RelativePath="..\platform\mock\GeolocationServiceMock.cpp"

+ 					>

+ 				</File>

+ 				<File

+ 					RelativePath="..\platform\mock\GeolocationServiceMock.h"

+ 					>

+ 				</File>

+ 			</Filter>

 		</Filter>

 		<Filter

 			Name="css"

diff --git a/WebCore/WebCore.vcproj/WebCoreCommon.vsprops b/WebCore/WebCore.vcproj/WebCoreCommon.vsprops
index 0f69ac2..5edead4 100644
--- a/WebCore/WebCore.vcproj/WebCoreCommon.vsprops
+++ b/WebCore/WebCore.vcproj/WebCoreCommon.vsprops
@@ -7,7 +7,7 @@
 	>
 	<Tool
 		Name="VCCLCompilerTool"
-		AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\accessibility&quot;;&quot;$(ProjectDir)..\accessibility\win&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\dom\default&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&quot;;&quot;$(ProjectDir)..\html\canvas&quot;;&quot;$(ProjectDir)..\inspector&quot;;&quot;$(ProjectDir)..\loader&quot;;&quot;$(ProjectDir)..\loader\appcache&quot;;&quot;$(ProjectDir)..\loader\archive&quot;;&quot;$(ProjectDir)..\loader\archive\cf&quot;;&quot;$(ProjectDir)..\loader\icon&quot;;&quot;$(ProjectDir)..\notifications&quot;;&quot;$(ProjectDir)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&quot;;&quot;$(ProjectDir)..\platform\sql&quot;;&quot;$(ProjectDir)..\platform\win&quot;;&quot;$(ProjectDir)..\platform\network&quot;;&quot;$(ProjectDir)..\platform\network\win&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\private\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+		AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\accessibility&quot;;&quot;$(ProjectDir)..\accessibility\win&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\dom\default&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&quot;;&quot;$(ProjectDir)..\html\canvas&quot;;&quot;$(ProjectDir)..\inspector&quot;;&quot;$(ProjectDir)..\loader&quot;;&quot;$(ProjectDir)..\loader\appcache&quot;;&quot;$(ProjectDir)..\loader\archive&quot;;&quot;$(ProjectDir)..\loader\archive\cf&quot;;&quot;$(ProjectDir)..\loader\icon&quot;;&quot;$(ProjectDir)..\notifications&quot;;&quot;$(ProjectDir)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&quot;;&quot;$(ProjectDir)..\platform\mock&quot;;&quot;$(ProjectDir)..\platform\sql&quot;;&quot;$(ProjectDir)..\platform\win&quot;;&quot;$(ProjectDir)..\platform\network&quot;;&quot;$(ProjectDir)..\platform\network\win&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\private\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
 		PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_CHANNEL_MESSAGING;ENABLE_DATABASE;ENABLE_DATAGRID;ENABLE_DATALIST;ENABLE_DOM_STORAGE;ENABLE_EVENTSOURCE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_RUBY;ENABLE_SHARED_WORKERS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_WEB_SOCKETS;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
 		UsePrecompiledHeader="2"
 		PrecompiledHeaderThrough="WebCorePrefix.h"
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index eac4448..2941a77 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -1015,6 +1015,8 @@
 		54C50F7B0E801DF3009832A0 /* XMLTokenizerLibxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 54C50F7A0E801DF3009832A0 /* XMLTokenizerLibxml2.cpp */; };
 		550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; };
 		550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		59C77F2A10545B3B00506104 /* GeolocationServiceMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59C77F2810545B3B00506104 /* GeolocationServiceMock.cpp */; };
+		59C77F2B10545B3B00506104 /* GeolocationServiceMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 59C77F2910545B3B00506104 /* GeolocationServiceMock.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5D15E3AB0F9E6AC1009E0E3F /* XMLTokenizerScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D15E3A90F9E6AC1009E0E3F /* XMLTokenizerScope.cpp */; };
 		5D15E3AC0F9E6AC1009E0E3F /* XMLTokenizerScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D15E3AA0F9E6AC1009E0E3F /* XMLTokenizerScope.h */; };
 		5D874F130D161D3200796C3B /* NetscapePlugInStreamLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E227DD0AF589AD00D48324 /* NetscapePlugInStreamLoader.cpp */; };
@@ -4614,7 +4616,7 @@
 		F916C48E0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F916C48C0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h */; };
 		F9F0ED7A0DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F9F0ED770DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h */; };
 		FE6FD4870F676E5700092873 /* Coordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD4840F676E5700092873 /* Coordinates.cpp */; };
-		FE6FD4880F676E5700092873 /* Coordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD4850F676E5700092873 /* Coordinates.h */; };
+		FE6FD4880F676E5700092873 /* Coordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD4850F676E5700092873 /* Coordinates.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE6FD48D0F676E9300092873 /* JSCoordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */; };
 		FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD48C0F676E9300092873 /* JSCoordinates.h */; };
 		FE700DD10F92D81A008E2BFE /* JSCoordinatesCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE700DD00F92D81A008E2BFE /* JSCoordinatesCustom.cpp */; };
@@ -4626,9 +4628,9 @@
 		FE80D7C50E9C1F25000D6F75 /* Geolocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7B70E9C1F25000D6F75 /* Geolocation.cpp */; };
 		FE80D7C60E9C1F25000D6F75 /* Geolocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7B80E9C1F25000D6F75 /* Geolocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE80D7C80E9C1F25000D6F75 /* Geoposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7BA0E9C1F25000D6F75 /* Geoposition.cpp */; };
-		FE80D7C90E9C1F25000D6F75 /* Geoposition.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BB0E9C1F25000D6F75 /* Geoposition.h */; };
+		FE80D7C90E9C1F25000D6F75 /* Geoposition.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BB0E9C1F25000D6F75 /* Geoposition.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE80D7CB0E9C1F25000D6F75 /* PositionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BD0E9C1F25000D6F75 /* PositionCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		FE80D7CD0E9C1F25000D6F75 /* PositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BF0E9C1F25000D6F75 /* PositionError.h */; };
+		FE80D7CD0E9C1F25000D6F75 /* PositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BF0E9C1F25000D6F75 /* PositionError.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE80D7CF0E9C1F25000D6F75 /* PositionErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7C10E9C1F25000D6F75 /* PositionErrorCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE80D7D10E9C1F25000D6F75 /* PositionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7C30E9C1F25000D6F75 /* PositionOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE80DA630E9C4703000D6F75 /* JSGeolocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */; };
@@ -6166,6 +6168,8 @@
 		54C50F7A0E801DF3009832A0 /* XMLTokenizerLibxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLTokenizerLibxml2.cpp; sourceTree = "<group>"; };
 		550A0BC7085F6039007353D6 /* QualifiedName.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifiedName.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
 		550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+		59C77F2810545B3B00506104 /* GeolocationServiceMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GeolocationServiceMock.cpp; path = mock/GeolocationServiceMock.cpp; sourceTree = "<group>"; };
+		59C77F2910545B3B00506104 /* GeolocationServiceMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeolocationServiceMock.h; path = mock/GeolocationServiceMock.h; sourceTree = "<group>"; };
 		5D15E3A90F9E6AC1009E0E3F /* XMLTokenizerScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLTokenizerScope.cpp; sourceTree = "<group>"; };
 		5D15E3AA0F9E6AC1009E0E3F /* XMLTokenizerScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLTokenizerScope.h; sourceTree = "<group>"; };
 		5D925B650F64D4DD00B847F0 /* ScrollBehavior.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollBehavior.cpp; sourceTree = "<group>"; };
@@ -10576,6 +10580,15 @@
 			path = websockets;
 			sourceTree = "<group>";
 		};
+		59C77F101054591C00506104 /* mock */ = {
+			isa = PBXGroup;
+			children = (
+				59C77F2810545B3B00506104 /* GeolocationServiceMock.cpp */,
+				59C77F2910545B3B00506104 /* GeolocationServiceMock.h */,
+			);
+			name = mock;
+			sourceTree = "<group>";
+		};
 		5DA5E0F9102B950400088CF9 /* WebSockets */ = {
 			isa = PBXGroup;
 			children = (
@@ -14370,6 +14383,7 @@
 		BCF1A5BA097832090061A123 /* platform */ = {
 			isa = PBXGroup;
 			children = (
+				59C77F101054591C00506104 /* mock */,
 				49E912A40EFAC8E6009D0CAF /* animation */,
 				1AE42F670AA4B8CB00C8612D /* cf */,
 				B2A015910AF6CD53006BCE0E /* graphics */,
@@ -17558,6 +17572,7 @@
 				510D4A38103165EE0049EA54 /* SocketStreamHandleClient.h in Headers */,
 				51ABAE1B103C18FF008C5260 /* SocketStreamError.h in Headers */,
 				51ABAE1E103C1913008C5260 /* SocketStreamHandle.h in Headers */,
+				59C77F2B10545B3B00506104 /* GeolocationServiceMock.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -19653,6 +19668,7 @@
 				510D4A33103165EE0049EA54 /* SocketStreamErrorBase.cpp in Sources */,
 				510D4A36103165EE0049EA54 /* SocketStreamHandleBase.cpp in Sources */,
 				51ABAE1F103C1913008C5260 /* SocketStreamHandleCFNet.cpp in Sources */,
+				59C77F2A10545B3B00506104 /* GeolocationServiceMock.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebCore/WebCoreSources.bkl b/WebCore/WebCoreSources.bkl
index 68e4e1f..402b94c 100644
--- a/WebCore/WebCoreSources.bkl
+++ b/WebCore/WebCoreSources.bkl
@@ -817,6 +817,7 @@
         platform/LinkHash.cpp
         platform/Logging.cpp
         platform/MIMETypeRegistry.cpp
+        platform/mock/GeolocationServiceMock.cpp
         platform/text/RegularExpression.cpp
         platform/Scrollbar.cpp
         platform/ScrollbarThemeComposite.cpp
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index ae9b7f7..2a1e991 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -175,7 +175,7 @@
                                           float value, float proportion, ScrollbarControlPartMask);
         virtual bool paintCustomScrollCorner(GraphicsContext*, const FloatRect&);
 
-        // This is an asynchronous call. The ChromeClient can display UI asking the user for permission
+        // This can be either a synchronous or asynchronous call. The ChromeClient can display UI asking the user for permission
         // to use Geolococation. The ChromeClient must call Geolocation::setShouldClearCache() appropriately.
         virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) = 0;
             
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 3f7e079..7b34aa3 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -145,7 +145,7 @@
         startTimers();
         makeSuccessCallbacks();
     } else {
-        WTF::RefPtr<WebCore::PositionError> error = WebCore::PositionError::create(PositionError::PERMISSION_DENIED, "User disallowed GeoLocation");
+        WTF::RefPtr<WebCore::PositionError> error = WebCore::PositionError::create(PositionError::PERMISSION_DENIED, "User disallowed Geolocation");
         handleError(error.get());
     }
 }
diff --git a/WebCore/platform/GeolocationService.cpp b/WebCore/platform/GeolocationService.cpp
index 9b362c8..8d5e769 100644
--- a/WebCore/platform/GeolocationService.cpp
+++ b/WebCore/platform/GeolocationService.cpp
@@ -20,23 +20,39 @@
  * 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. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
 #include "GeolocationService.h"
+#include "Geoposition.h"
+#include "GeolocationServiceMock.h"
+#include "PositionError.h"
 
+#include <wtf/CurrentTime.h>
 #include <wtf/Assertions.h>
 
 namespace WebCore {
 
 #if !ENABLE(GEOLOCATION)
-GeolocationService* GeolocationService::create(GeolocationServiceClient*)
+GeolocationService* createGeolocationServiceNull(GeolocationServiceClient*)
 {
     return 0;
 }
+
+GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &createGeolocationServiceNull;
 #endif
 
+GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+{
+    return (*s_factoryFunction)(client);
+}
+
+void GeolocationService::useMock()
+{
+    s_factoryFunction = &GeolocationServiceMock::create;
+}
+
 GeolocationService::GeolocationService(GeolocationServiceClient* client)
     : m_geolocationServiceClient(client)
 {
diff --git a/WebCore/platform/GeolocationService.h b/WebCore/platform/GeolocationService.h
index 74a6ead..cebf313 100644
--- a/WebCore/platform/GeolocationService.h
+++ b/WebCore/platform/GeolocationService.h
@@ -59,11 +59,16 @@
     void positionChanged();
     void errorOccurred();
 
+    static void useMock();
+
 protected:
     GeolocationService(GeolocationServiceClient*);
 
 private:
     GeolocationServiceClient* m_geolocationServiceClient;
+
+    typedef GeolocationService* (FactoryFunction)(GeolocationServiceClient*);
+    static FactoryFunction* s_factoryFunction;
 };
 
 } // namespace WebCore
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.cpp b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
index fc15833..cf35346 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.cpp
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
@@ -37,11 +37,13 @@
 
 namespace WebCore {
 
-GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+GeolocationService* GeolocationServiceGtk::create(GeolocationServiceClient* client)
 {
     return new GeolocationServiceGtk(client);
 }
 
+GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceGtk::create;
+
 GeolocationServiceGtk::GeolocationServiceGtk(GeolocationServiceClient* client)
     : GeolocationService(client)
     , m_geoclueClient(0)
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.h b/WebCore/platform/gtk/GeolocationServiceGtk.h
index 90699ad..a198dc0 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.h
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.h
@@ -31,7 +31,7 @@
 namespace WebCore {
     class GeolocationServiceGtk : public GeolocationService {
     public:
-        GeolocationServiceGtk(GeolocationServiceClient*);
+        static GeolocationService* create(GeolocationServiceClient*);
         ~GeolocationServiceGtk();
 
         virtual bool startUpdating(PositionOptions*);
@@ -44,6 +44,8 @@
         PositionError* lastError() const;
 
     private:
+        GeolocationServiceGtk(GeolocationServiceClient*);
+
         void updateLocationInformation();
         void setError(PositionError::ErrorCode, const char* message);
         void updatePosition();
diff --git a/WebCore/platform/mac/GeolocationServiceMac.h b/WebCore/platform/mac/GeolocationServiceMac.h
index d0342e7..4beefca 100644
--- a/WebCore/platform/mac/GeolocationServiceMac.h
+++ b/WebCore/platform/mac/GeolocationServiceMac.h
@@ -45,7 +45,7 @@
 
 class GeolocationServiceMac : public GeolocationService {
 public:
-    GeolocationServiceMac(GeolocationServiceClient*);
+    static GeolocationService* create(GeolocationServiceClient*);
     virtual ~GeolocationServiceMac();
     
     virtual bool startUpdating(PositionOptions*);
@@ -61,6 +61,8 @@
     void errorOccurred(PassRefPtr<PositionError>);
 
 private:
+    GeolocationServiceMac(GeolocationServiceClient*);
+
     RetainPtr<CLLocationManager> m_locationManager;
     RetainPtr<WebCoreCoreLocationObserver> m_objcObserver;
     
diff --git a/WebCore/platform/mac/GeolocationServiceMac.mm b/WebCore/platform/mac/GeolocationServiceMac.mm
index 01eca4a..1093e69 100644
--- a/WebCore/platform/mac/GeolocationServiceMac.mm
+++ b/WebCore/platform/mac/GeolocationServiceMac.mm
@@ -65,11 +65,13 @@
 
 namespace WebCore {
 
-GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+GeolocationService* GeolocationServiceMac::create(GeolocationServiceClient* client)
 {
     return new GeolocationServiceMac(client);
 }
 
+GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceMac::create;
+
 GeolocationServiceMac::GeolocationServiceMac(GeolocationServiceClient* client)
     : GeolocationService(client)
     , m_objcObserver(AdoptNS, [[WebCoreCoreLocationObserver alloc] initWithCallback:this])
diff --git a/WebCore/platform/mock/GeolocationServiceMock.cpp b/WebCore/platform/mock/GeolocationServiceMock.cpp
new file mode 100644
index 0000000..f187104
--- /dev/null
+++ b/WebCore/platform/mock/GeolocationServiceMock.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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 APPLE INC. ``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 APPLE INC. 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 "GeolocationServiceMock.h"
+
+#include "Logging.h"
+#include "Geolocation.h"
+#include "Geoposition.h"
+#include "PositionError.h"
+#include "PositionOptions.h"
+
+namespace WebCore {
+
+GeolocationServiceMock::GeolocationServiceSet* GeolocationServiceMock::s_instances = 0;
+RefPtr<Geoposition>* GeolocationServiceMock::s_lastPosition;
+RefPtr<PositionError>* GeolocationServiceMock::s_lastError;
+
+GeolocationService* GeolocationServiceMock::create(GeolocationServiceClient* client)
+{
+    initStatics();
+    return new GeolocationServiceMock(client);
+}
+
+GeolocationServiceMock::GeolocationServiceMock(GeolocationServiceClient* client)
+    : GeolocationService(client)
+    , m_timer(this, &GeolocationServiceMock::timerFired)
+    , m_isActive(false)
+{
+    s_instances->add(this);
+}
+
+GeolocationServiceMock::~GeolocationServiceMock()
+{
+    GeolocationServiceSet::iterator iter = s_instances->find(this);
+    ASSERT(iter != s_instances->end());
+    s_instances->remove(iter);
+    cleanUpStatics();
+}
+
+void GeolocationServiceMock::setPosition(PassRefPtr<Geoposition> position)
+{
+    initStatics();
+    GeolocationService::useMock();
+    *s_lastPosition = position;
+    *s_lastError = 0;
+    makeGeolocationCallbackFromAllInstances();
+}
+
+void GeolocationServiceMock::setError(PassRefPtr<PositionError> error)
+{
+    initStatics();
+    GeolocationService::useMock();
+    *s_lastError = error;
+    *s_lastPosition = 0;
+    makeGeolocationCallbackFromAllInstances();
+}
+
+bool GeolocationServiceMock::startUpdating(PositionOptions*)
+{
+    m_isActive = true;
+    m_timer.startOneShot(0);
+    return true;
+}
+
+void GeolocationServiceMock::stopUpdating()
+{
+    m_isActive = false;
+}
+
+void GeolocationServiceMock::timerFired(Timer<GeolocationServiceMock>* timer)
+{
+    ASSERT_UNUSED(timer, timer == &m_timer);
+    makeGeolocationCallback();
+}
+
+void GeolocationServiceMock::makeGeolocationCallbackFromAllInstances()
+{
+    GeolocationServiceSet::const_iterator end = s_instances->end();
+    for (GeolocationServiceSet::const_iterator iter = s_instances->begin(); iter != end; ++iter)
+        (*iter)->makeGeolocationCallback();
+}
+
+void GeolocationServiceMock::makeGeolocationCallback()
+{
+    if (!m_isActive)
+        return;
+
+    if (*s_lastPosition)
+        positionChanged();
+    else if (*s_lastError)
+        errorOccurred();
+}
+
+void GeolocationServiceMock::initStatics()
+{
+    if (s_instances == 0) { 
+        s_instances = new GeolocationServiceSet;
+        s_lastPosition = new RefPtr<Geoposition>;
+        s_lastError = new RefPtr<PositionError>;
+    }
+}
+
+void GeolocationServiceMock::cleanUpStatics()
+{
+    if (s_instances->size() == 0) {
+        delete s_instances;
+        s_instances = 0;
+        delete s_lastPosition;
+        delete s_lastError;
+    }
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/mock/GeolocationServiceMock.h b/WebCore/platform/mock/GeolocationServiceMock.h
new file mode 100644
index 0000000..7d02797
--- /dev/null
+++ b/WebCore/platform/mock/GeolocationServiceMock.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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 APPLE INC. ``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 APPLE INC. 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 GeolocationServiceMock_h
+#define GeolocationServiceMock_h
+
+#include "GeolocationService.h"
+#include "Timer.h"
+#include <wtf/HashSet.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+// This class provides a mock implementation of a GeolocationService for testing
+// purposes. It allows the position or error that will be reported by this class
+// to be set manually using the setPosition and setError methods. Objects of
+// this class call back to their respective GeolocationServiceClient with the
+// position or error every time either of these is updated.
+class GeolocationServiceMock : public GeolocationService {
+  public:
+    static GeolocationService* create(GeolocationServiceClient*);
+
+    GeolocationServiceMock(GeolocationServiceClient*);
+    virtual ~GeolocationServiceMock();
+
+    virtual bool startUpdating(PositionOptions*);
+    virtual void stopUpdating();
+
+    static void setPosition(PassRefPtr<Geoposition> position);
+    static void setError(PassRefPtr<PositionError> position);
+
+    virtual Geoposition* lastPosition() const { return s_lastPosition->get(); }
+    virtual PositionError* lastError() const { return s_lastError->get(); }
+
+  private:
+    static void makeGeolocationCallbackFromAllInstances();
+    void makeGeolocationCallback();
+
+    void timerFired(Timer<GeolocationServiceMock>*);
+
+    static void initStatics();
+    static void cleanUpStatics();
+
+    typedef HashSet<GeolocationServiceMock*> GeolocationServiceSet;
+    static GeolocationServiceSet* s_instances;
+
+    static RefPtr<Geoposition>* s_lastPosition;
+    static RefPtr<PositionError>* s_lastError;
+
+    Timer<GeolocationServiceMock> m_timer;
+
+    bool m_isActive;
+};
+
+} // namespace WebCore
+
+#endif // GeolocationServiceMock_h