Inital geolocation implementation. bug=437948, r/sr=jst
authorDoug Turner <dougt@meer.net>
Tue, 15 Jul 2008 16:37:48 -0700
changeset 15958 46b8c45ac8775fd5a53fc76728141b3b8b708841
parent 15957 320afc8e0d25bbac1f38d128e6a3d2c9d9a4d9ca
child 15959 76f62ca289969ebc626df912ab120bc6a560b718
push idunknown
push userunknown
push dateunknown
bugs437948
milestone1.9.1a1pre
Inital geolocation implementation. bug=437948, r/sr=jst
dom/public/idl/Makefile.in
dom/public/idl/geolocation/Makefile.in
dom/public/idl/geolocation/nsIDOMGeolocation.idl
dom/public/idl/geolocation/nsIDOMGeolocationCallback.idl
dom/public/idl/geolocation/nsIDOMGeolocator.idl
dom/public/idl/geolocation/nsIDOMNavigatorGeolocator.idl
dom/public/idl/geolocation/nsIGeolocationProvider.idl
dom/public/nsDOMClassInfoID.h
dom/src/Makefile.in
dom/src/base/Makefile.in
dom/src/base/nsDOMClassInfo.cpp
dom/src/base/nsGlobalWindow.cpp
dom/src/base/nsGlobalWindow.h
dom/src/geolocation/MaemoLocationProvider.cpp
dom/src/geolocation/MaemoLocationProvider.h
dom/src/geolocation/Makefile.in
dom/src/geolocation/nsGeolocation.cpp
dom/src/geolocation/nsGeolocation.h
dom/tests/mochitest/Makefile.in
dom/tests/mochitest/geolocation/Makefile.in
dom/tests/mochitest/geolocation/geolocation_common.js
dom/tests/mochitest/geolocation/geolocator.html
dom/tests/mochitest/geolocation/prompt_common.js
dom/tests/mochitest/geolocation/test_lastPosition.html
dom/tests/mochitest/geolocation/test_manyWindows.html
layout/build/Makefile.in
layout/build/nsLayoutModule.cpp
toolkit/library/Makefile.in
--- a/dom/public/idl/Makefile.in
+++ b/dom/public/idl/Makefile.in
@@ -54,16 +54,17 @@ DIRS =						\
 	traversal				\
 	range					\
 	xbl					\
 	xpath					\
 	ls					\
 	xul                                     \
 	storage                                 \
 	json                                    \
-	offline
+	offline                                 \
+	geolocation
 
 ifdef MOZ_SVG
 DIRS += svg
 endif
 
 include $(topsrcdir)/config/rules.mk
 
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/geolocation/Makefile.in
@@ -0,0 +1,57 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org build system.
+#
+# The Initial Developer of the Original Code is Mozilla Corporation
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Doug Turner <dougt@meer.net>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+DEPTH          = ../../../..
+topsrcdir      = @top_srcdir@
+srcdir         = @srcdir@
+VPATH          = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE         = dom
+XPIDL_MODULE   = dom_geolocation
+GRE_MODULE     = 1
+
+XPIDLSRCS = \
+			nsIDOMGeolocation.idl            \
+			nsIDOMGeolocationCallback.idl    \
+			nsIDOMGeolocator.idl             \
+			nsIDOMNavigatorGeolocator.idl    \
+			nsIGeolocationProvider.idl       \
+            $(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/geolocation/nsIDOMGeolocation.idl
@@ -0,0 +1,51 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "domstubs.idl"
+
+[scriptable, uuid(CEEBF85D-F5E2-4E27-981A-0BF8705ABF0A)]
+interface nsIDOMGeolocation : nsISupports
+{
+  readonly attribute double latitude;
+  readonly attribute double longitude;
+  readonly attribute double altitude;
+
+  readonly attribute double horizontalAccuracy;
+  readonly attribute double verticalAccuracy;
+
+  readonly attribute DOMTimeStamp timestamp;
+};
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/geolocation/nsIDOMGeolocationCallback.idl
@@ -0,0 +1,45 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "domstubs.idl"
+
+interface nsIDOMGeolocation;
+
+[scriptable, function, uuid(679C8833-5D8C-430D-A7A3-FF13FE082098)]
+interface nsIDOMGeolocationCallback : nsISupports {
+  void onRequest(in nsIDOMGeolocation position);
+};
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/geolocation/nsIDOMGeolocator.idl
@@ -0,0 +1,54 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+#include "domstubs.idl"
+
+interface nsIDOMGeolocation;
+interface nsIDOMGeolocationCallback;
+
+[scriptable, uuid(3C3B69FF-3AFA-4D4C-BA3A-F03940E74E14)]
+interface nsIDOMGeolocator : nsISupports
+{
+  readonly attribute nsIDOMGeolocation lastPosition;
+
+  void getCurrentPosition(in nsIDOMGeolocationCallback callback);
+
+  unsigned short watchPosition(in nsIDOMGeolocationCallback callback);
+
+  void clearWatch(in unsigned short watchId);
+};
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/geolocation/nsIDOMNavigatorGeolocator.idl
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+#include "domstubs.idl"
+interface nsIDOMGeolocator;
+
+/**
+ * Property that extends the navigator object.
+ */
+[scriptable, uuid(1470B9BC-F17C-4419-85A4-E6C1742977A3)]
+interface nsIDOMNavigatorGeolocator : nsISupports
+{
+  readonly attribute nsIDOMGeolocator geolocator;
+};
+
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/geolocation/nsIGeolocationProvider.idl
@@ -0,0 +1,141 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+#include "nsISupports.idl"
+
+interface nsIURI;
+interface nsIDOMWindow;
+interface nsIDOMGeolocation;
+interface nsIGeolocationPrompt;
+
+/**
+ * nsIGeolocationService
+ */
+[scriptable, uuid(68300FFD-802C-431B-BF92-0A657696B853)]
+interface nsIGeolocationService : nsISupports {
+  attribute nsIGeolocationPrompt prompt;
+};
+
+/**
+ * Interface allows access to a geolocation and is passed to
+ * the nsIGeolocationPrompt so that the application can approve
+ * or deny the request.
+ */
+[scriptable, function, uuid(D681C322-C075-4C6E-9765-C22711A4A60E)]
+interface nsIGeolocationRequest : nsISupports {
+
+  readonly attribute nsIURI requestingURI;
+  readonly attribute nsIDOMWindow requestingWindow;
+
+  void cancel();
+  void allow();
+  void allowButFuzz();
+};
+
+/**
+ * Interface provides a way for the application to handle
+ * the UI prompts associated with geolocation.
+ */
+[scriptable, function, uuid(2300C895-1BEE-4297-912C-A57082F3E936)]
+interface nsIGeolocationPrompt : nsISupports {
+  /**
+   * Called when a request has been made to access geolocation data
+   */
+  void prompt(in nsIGeolocationRequest request);
+};
+
+/** 
+ * Interface provides a way for a geolocation provider to
+ * notify the system that a new location is available.
+ */
+[scriptable, uuid(B89D7227-9F04-4236-A582-25A3F2779D72)]
+interface nsIGeolocationUpdate : nsISupports {
+
+  /**
+   * Notify the geolocation service that a new geolocation
+   * has been discovered.
+   * This must be called on the main thread
+   */
+  void update(in nsIDOMGeolocation location);
+};
+
+
+/**
+ * Interface provides location information to the nsGeolocator
+ * via the nsIDOMGeolocationCallback interface.  After
+ * startup is called, any geo location change should call
+ * callback.onRequest().
+ */
+[scriptable, uuid(E319BE2D-B1D1-4CA6-AEF4-66178589B63D)]
+interface nsIGeolocationProvider : nsISupports {
+
+  /**
+   * Start up the provider.  This is called before any other
+   * method.  may be called multiple times.
+   */
+  void startup();
+
+  /**
+   * Returns true when the devices is ready and has a
+   * postion, otherwise false.
+   */
+   boolean isReady();
+
+  /**
+   * watch
+   * When a location change is observed, notify the callback
+   */
+  void watch(in nsIGeolocationUpdate callback);
+
+  /**
+   * currentLocation return the current location as seen by
+   * the provider.  may be null.
+   */
+  readonly attribute nsIDOMGeolocation currentLocation;
+  
+  /**
+   * shutdown
+   * Shuts down the location devices.
+   */
+  void shutdown();
+};
+
+%{C++
+#define NS_GEOLOCATION_SERVICE_CONTRACTID  "@mozilla.org/geolocation/service;1"
+#define NS_GEOLOCATION_PROVIDER_CONTRACTID "@mozilla.org/geolocation/provider;1"
+%}
--- a/dom/public/nsDOMClassInfoID.h
+++ b/dom/public/nsDOMClassInfoID.h
@@ -419,16 +419,20 @@ enum nsDOMClassInfoID {
 
   // Data Events
   eDOMClassInfo_DataContainerEvent_id,
 
   // event used for cross-domain message-passing and for server-sent events in
   // HTML5
   eDOMClassInfo_MessageEvent_id,
 
+  // Geolocation
+  eDOMClassInfo_Geolocation_id,
+  eDOMClassInfo_Geolocator_id,
+
   // WhatWG Video Element
 #if defined(MOZ_MEDIA)
   eDOMClassInfo_HTMLVideoElement_id,
   eDOMClassInfo_HTMLSourceElement_id,
   eDOMClassInfo_ProgressEvent_id,
   eDOMClassInfo_HTMLMediaError_id,
   eDOMClassInfo_HTMLAudioElement_id,
 #endif
--- a/dom/src/Makefile.in
+++ b/dom/src/Makefile.in
@@ -37,17 +37,17 @@
 
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS		= base jsurl events storage offline json
+DIRS		= base jsurl events storage offline json geolocation
 
 include $(topsrcdir)/config/rules.mk
 
 _FILES = \
 	$(srcdir)/res/hiddenWindow.html \
 	$(NULL)
 
 libs::
--- a/dom/src/base/Makefile.in
+++ b/dom/src/base/Makefile.in
@@ -119,16 +119,17 @@ CPPSRCS =			\
 # we don't want the shared lib, but we want to force the creation of a
 # static lib.
 FORCE_STATIC_LIB = 1
 
 LOCAL_INCLUDES = \
 		-I$(srcdir)/../events \
 		-I$(srcdir)/../storage \
 		-I$(srcdir)/../offline \
+		-I$(srcdir)/../geolocation \
 		-I$(topsrcdir)/content/xbl/src \
 		-I$(topsrcdir)/content/xul/document/src \
 		-I$(topsrcdir)/content/events/src \
 		-I$(topsrcdir)/content/base/src \
 		-I$(topsrcdir)/content/html/document/src \
 		-I$(topsrcdir)/layout/style \
 		$(NULL)
 
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -448,16 +448,20 @@
 #include "nsIDOMStorageEvent.h"
 #include "nsIDOMToString.h"
 
 // Offline includes
 #include "nsIDOMLoadStatusList.h"
 #include "nsIDOMLoadStatus.h"
 #include "nsIDOMLoadStatusEvent.h"
 
+// Geolocation
+#include "nsIDOMGeolocation.h"
+#include "nsIDOMGeolocator.h"
+
 #include "nsIDOMFileList.h"
 #include "nsIDOMFile.h"
 #include "nsIDOMFileException.h"
 
 static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
 static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 static const char kDOMStringBundleURL[] =
@@ -1237,16 +1241,22 @@ static nsDOMClassInfoData sClassInfoData
                            WINDOW_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MessageEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
+  NS_DEFINE_CLASSINFO_DATA(Geolocation, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+ 
+   NS_DEFINE_CLASSINFO_DATA(Geolocator, nsDOMGenericSH,
+                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
 #if defined(MOZ_MEDIA) 
   NS_DEFINE_CLASSINFO_DATA(HTMLVideoElement, nsHTMLElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLSourceElement, nsHTMLElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ProgressEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLMediaError, nsDOMGenericSH,
@@ -1918,16 +1928,17 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(Location, nsIDOMLocation)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocation)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSLocation)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSNavigator)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPlugin)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(PluginArray, nsIDOMPluginArray)
@@ -3400,16 +3411,24 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataContainerEvent)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MessageEvent, nsIDOMMessageEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMessageEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(Geolocation, nsIDOMGeolocation)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeolocation)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(Geolocator, nsIDOMGeolocator)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeolocator)
+  DOM_CLASSINFO_MAP_END
+
 #if defined(MOZ_MEDIA)
   DOM_CLASSINFO_MAP_BEGIN(HTMLVideoElement, nsIDOMHTMLVideoElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLVideoElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLSourceElement, nsIDOMHTMLSourceElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLSourceElement)
--- a/dom/src/base/nsGlobalWindow.cpp
+++ b/dom/src/base/nsGlobalWindow.cpp
@@ -68,16 +68,17 @@
 #include "nsEscape.h"
 #include "nsStyleCoord.h"
 #include "nsMimeTypeArray.h"
 #include "nsNetUtil.h"
 #include "nsICachingChannel.h"
 #include "nsPluginArray.h"
 #include "nsIPluginHost.h"
 #include "nsPIPluginHost.h"
+#include "nsGeolocation.h"
 #ifdef OJI
 #include "nsIJVMManager.h"
 #include "nsILiveConnectManager.h"
 #endif
 #include "nsContentCID.h"
 #include "nsLayoutStatics.h"
 #include "nsCycleCollector.h"
 #include "nsCCUncollectableMarker.h"
@@ -106,16 +107,17 @@
 #include "nsIDOMEvent.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMessageEvent.h"
 #include "nsIDOMPopupBlockedEvent.h"
 #include "nsIDOMPkcs11.h"
 #include "nsIDOMOfflineResourceList.h"
+#include "nsIDOMGeolocation.h"
 #include "nsDOMString.h"
 #include "nsIEmbeddingSiteWindow2.h"
 #include "nsThreadUtils.h"
 #include "nsIEventStateManager.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsIJSContextStack.h"
 #include "nsIJSRuntimeService.h"
 #include "nsIMarkupDocumentViewer.h"
@@ -9003,30 +9005,38 @@ nsNavigator::~nsNavigator()
 
 
 // QueryInterface implementation for nsNavigator
 NS_INTERFACE_MAP_BEGIN(nsNavigator)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMJSNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocator)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_ADDREF(nsNavigator)
 NS_IMPL_RELEASE(nsNavigator)
 
 
 void
 nsNavigator::SetDocShell(nsIDocShell *aDocShell)
 {
   mDocShell = aDocShell;
   if (mPlugins)
     mPlugins->SetDocShell(aDocShell);
+
+  // if there is a page transition, make sure delete the geolocation object
+  if (mGeolocator)
+  {
+    mGeolocator->Shutdown();
+    mGeolocator = nsnull;
+  }
 }
 
 //*****************************************************************************
 //    nsNavigator::nsIDOMNavigator
 //*****************************************************************************
 
 NS_IMETHODIMP
 nsNavigator::GetUserAgent(nsAString& aUserAgent)
@@ -9537,16 +9547,22 @@ nsNavigator::Preference()
 void
 nsNavigator::LoadingNewDocument()
 {
   // Release these so that they will be recreated for the
   // new document (if requested).  The plugins or mime types
   // arrays may have changed.  See bug 150087.
   mMimeTypes = nsnull;
   mPlugins = nsnull;
+
+  if (mGeolocator)
+  {
+    mGeolocator->Shutdown();
+    mGeolocator = nsnull;
+  }
 }
 
 nsresult
 nsNavigator::RefreshMIMEArray()
 {
   nsresult rv = NS_OK;
   if (mMimeTypes)
     rv = mMimeTypes->Refresh();
@@ -9657,8 +9673,25 @@ nsNavigator::MozIsLocallyAvailable(const
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     *aIsAvailable = PR_FALSE;
   }
 
   return NS_OK;
 }
 
+//*****************************************************************************
+//    nsNavigator::nsIDOMNavigatorGeolocator
+//*****************************************************************************
+
+NS_IMETHODIMP nsNavigator::GetGeolocator(nsIDOMGeolocator **_retval)
+{
+  NS_ENSURE_ARG_POINTER(_retval);
+
+  if (!mGeolocator) {
+    nsCOMPtr<nsIDOMWindow> contentDOMWindow(do_GetInterface(mDocShell));
+    mGeolocator = new nsGeolocator(contentDOMWindow);
+  }
+
+  NS_IF_ADDREF(*_retval = mGeolocator);
+  return NS_OK;
+}
+
--- a/dom/src/base/nsGlobalWindow.h
+++ b/dom/src/base/nsGlobalWindow.h
@@ -60,16 +60,17 @@
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMClientInformation.h"
 #include "nsIDOMViewCSS.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOM3EventTarget.h"
 #include "nsIDOMNSEventTarget.h"
 #include "nsIDOMNavigator.h"
+#include "nsIDOMNavigatorGeolocator.h"
 #include "nsIDOMNSLocation.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDOMJSWindow.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
@@ -119,16 +120,17 @@ class nsIDocShellLoadInfo;
 class WindowStateHolder;
 class nsGlobalWindowObserver;
 class nsGlobalWindow;
 class nsDummyJavaPluginOwner;
 class PostMessageEvent;
 
 class nsDOMOfflineResourceList;
 class nsDOMOfflineLoadStatusList;
+class nsGeolocator;
 
 // permissible values for CheckOpenAllow
 enum OpenAllowValue {
   allowNot = 0,     // the window opening is denied
   allowNoAbuse,     // allowed: not a popup
   allowWhitelisted  // allowed: it's whitelisted or popup blocking is disabled
 };
 
@@ -799,39 +801,42 @@ protected:
 
 
 //*****************************************************************************
 // nsNavigator: Script "navigator" object
 //*****************************************************************************
 
 class nsNavigator : public nsIDOMNavigator,
                     public nsIDOMJSNavigator,
-                    public nsIDOMClientInformation
+                    public nsIDOMClientInformation,
+                    public nsIDOMNavigatorGeolocator
 {
 public:
   nsNavigator(nsIDocShell *aDocShell);
   virtual ~nsNavigator();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMNAVIGATOR
   NS_DECL_NSIDOMJSNAVIGATOR
   NS_DECL_NSIDOMCLIENTINFORMATION
+  NS_DECL_NSIDOMNAVIGATORGEOLOCATOR
   
   void SetDocShell(nsIDocShell *aDocShell);
   nsIDocShell *GetDocShell()
   {
     return mDocShell;
   }
 
   void LoadingNewDocument();
   nsresult RefreshMIMEArray();
 
 protected:
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
+  nsRefPtr<nsGeolocator> mGeolocator;
   nsIDocShell* mDocShell; // weak reference
 
   static jsval       sPrefInternal_id;
 };
 
 class nsIURI;
 
 //*****************************************************************************
new file mode 100644
--- /dev/null
+++ b/dom/src/geolocation/MaemoLocationProvider.cpp
@@ -0,0 +1,119 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+#include "MaemoLocationProvider.h"
+#include "nsGeolocation.h"
+
+NS_IMPL_ISUPPORTS1(MaemoLocationProvider, nsIGeolocationProvider)
+
+MaemoLocationProvider::MaemoLocationProvider()
+: mGPSDevice(nsnull), mLocationCallbackHandle(0), mHasSeenLocation(PR_FALSE)
+{
+}
+
+MaemoLocationProvider::~MaemoLocationProvider()
+{
+}
+
+void location_changed (LocationGPSDevice *device, gpointer userdata)
+{
+  MaemoLocationProvider* provider = (MaemoLocationProvider*) userdata;
+  nsRefCnt<nsGeolocation*> somewhere = new nsGeolocation(device->fix->latitude,
+                                                         device->fix->longitude,
+                                                         device->fix->altitude,
+                                                         device->fix->eph,
+                                                         device->fix->epv,
+                                                         device->fix->time);
+  provider->Update(somewhere);
+}
+
+NS_IMETHODIMP MaemoLocationProvider::Startup()
+{
+  if (!mGPSDevice)
+  {
+    // if we are already started, don't do anything
+    memset(&mGPSBT, 0, sizeof(gpsbt_t));
+    int result = gpsbt_start(NULL, 0, 0, 0, NULL, 0, 0, &mGPSBT);
+    if (result <0)
+      return NS_ERROR_NOT_AVAILABLE;
+    
+    mGPSDevice = (LocationGPSDevice*) g_object_new (LOCATION_TYPE_GPS_DEVICE, NULL);
+    mLocationCallbackHandle = g_signal_connect (mGPSDevice, "changed", G_CALLBACK (location_changed), this->mCallback);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP MaemoLocationProvider::IsReady(PRBool *_retval NS_OUTPARAM)
+{
+  *_retval = mHasSeenLocation;
+  return NS_OK;
+}
+
+NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback)
+{
+  mCallback = callback; // weak ref
+  return NS_OK;
+}
+
+/* readonly attribute nsIDOMGeolocation currentLocation; */
+NS_IMETHODIMP MaemoLocationProvider::GetCurrentLocation(nsIDOMGeolocation * *aCurrentLocation)
+{
+  NS_IF_ADDREF(*aCurrentLocation = mLastLocation);
+  return NS_OK;
+}
+
+NS_IMETHODIMP MaemoLocationProvider::Shutdown()
+{
+  if (mGPSDevice && mLocationCallbackHandle) {
+    g_signal_handler_disconnect(mGPSDevice, mLocationCallbackHandle);
+    g_object_unref(mGPSDevice);
+    gpsbt_stop(&mGPSBT);
+    mLocationCallbackHandle = 0;
+    mGPSDevice = nsnull;
+    mHasSeenLocation = PR_FALSE;
+  }
+  return NS_OK;
+}
+
+void MaemoLocationProvider::Update(nsIDOMGeolocation* aLocation)
+{
+  mHasSeenLocation = PR_TRUE;
+  mLastLocation = aLocation;
+  if (mCallback)
+    mCallback->Update(aLocation);
+}
new file mode 100644
--- /dev/null
+++ b/dom/src/geolocation/MaemoLocationProvider.h
@@ -0,0 +1,75 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIGeolocationProvider.h"
+#include "nsIDOMGeolocation.h"
+#include "nsCOMPtr.h"
+
+#include <glib.h>
+#include <errno.h>
+#include <gpsbt.h>
+#include <gpsmgr.h>
+
+extern "C" {
+  // need to extern these because of:
+  // https://bugs.maemo.org/show_bug.cgi?id=3226
+  #include <location/location-gps-device.h>
+  #include <location/location-gpsd-control.h>
+}
+
+class MaemoLocationProvider : public nsIGeolocationProvider
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIGEOLOCATIONPROVIDER
+
+  MaemoLocationProvider();
+
+  void Update(nsIDOMGeolocation* aLocation);
+
+private:
+  ~MaemoLocationProvider();
+
+  nsCOMPtr<nsIDOMGeolocation> mLastLocation;
+
+  nsIGeolocationUpdate* mCallback; // weak reference by contract.
+
+
+  gpsbt_t mGPSBT;
+  LocationGPSDevice *mGPSDevice;
+  gulong mLocationCallbackHandle;
+  PRBool mHasSeenLocation;
+};
new file mode 100644
--- /dev/null
+++ b/dom/src/geolocation/Makefile.in
@@ -0,0 +1,84 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org build system.
+#
+# The Initial Developer of the Original Code is Mozilla Corporation
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Doug Turner <dougt@meer.net>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE         = dom
+LIBRARY_NAME   = jsdomgeolocation_s
+LIBXUL_LIBRARY = 1
+
+# we don't want the shared lib, but we want to force the creation of a static lib.
+FORCE_STATIC_LIB = 1
+
+REQUIRES = \
+        xpcom \
+		content \
+        layout \
+		pref \
+		widget \
+		string \
+		dom \
+		js \
+		caps \
+		xpconnect\
+		intl \
+		necko \
+		windowwatcher \
+		$(NULL)
+
+CPPSRCS		= \
+		nsGeolocation.cpp \
+		$(NULL)
+
+EXTRA_DSO_LDOPTS = \
+		$(MOZ_COMPONENT_LIBS) \
+		$(NULL)
+
+LOCAL_INCLUDES = \
+		-I$(srcdir)/../base \
+		$(NULL)
+
+ifdef NS_OSSO
+CPPSRCS		+= MaemoLocationProvider.cpp
+LOCAL_INCLUDES	+= $(MOZ_GTK2_CFLAGS)
+endif
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -0,0 +1,612 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsGeolocation.h"
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMWindow.h"
+#include "nsDOMClassInfo.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsContentUtils.h"
+#include "nsIURI.h"
+#include "nsIPermissionManager.h"
+#include "nsIObserverService.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch2.h"
+
+#ifdef NS_OSSO
+#include "MaemoLocationProvider.h"
+#endif
+
+#include "nsIDOMDocument.h"
+#include "nsIDocument.h"
+////////////////////////////////////////////////////
+// nsGeolocationRequest
+////////////////////////////////////////////////////
+
+nsGeolocationRequest::nsGeolocationRequest(nsGeolocator* locator, nsIDOMGeolocationCallback* callback)
+  : mAllowed(PR_FALSE), mCleared(PR_FALSE), mFuzzLocation(PR_FALSE), mCallback(callback), mLocator(locator)
+{
+}
+
+nsGeolocationRequest::~nsGeolocationRequest()
+{
+}
+
+NS_INTERFACE_MAP_BEGIN(nsGeolocationRequest)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGeolocationRequest)
+  NS_INTERFACE_MAP_ENTRY(nsIGeolocationRequest)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(nsGeolocationRequest)
+NS_IMPL_RELEASE(nsGeolocationRequest)
+
+NS_IMETHODIMP
+nsGeolocationRequest::GetRequestingURI(nsIURI * *aRequestingURI)
+{
+  NS_ENSURE_ARG_POINTER(aRequestingURI);
+  *aRequestingURI = mLocator->GetURI();
+  NS_IF_ADDREF(*aRequestingURI);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocationRequest::GetRequestingWindow(nsIDOMWindow * *aRequestingWindow)
+{
+  NS_ENSURE_ARG_POINTER(aRequestingWindow);
+  *aRequestingWindow = mLocator->GetOwner();
+  NS_IF_ADDREF(*aRequestingWindow);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocationRequest::Cancel()
+{
+  // pass a null back.
+  mCallback->OnRequest(nsnull);
+
+  // remove ourselves from the locators callback lists.
+  mLocator->RemoveRequest(this);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocationRequest::Allow()
+{
+  // Kick off the geo device, if it isn't already running
+  nsRefPtr<nsGeolocatorService> geoService = nsGeolocatorService::GetInstance();
+  geoService->StartDevice();
+
+  mAllowed = PR_TRUE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocationRequest::AllowButFuzz()
+{
+  mFuzzLocation = PR_TRUE;
+  return Allow();
+}
+
+void
+nsGeolocationRequest::MarkCleared()
+{
+  mCleared = PR_TRUE;
+}
+
+void
+nsGeolocationRequest::SendLocation(nsIDOMGeolocation* location)
+{
+  if (mCleared)
+    return;
+
+  //TODO mFuzzLocation.  Needs to be defined what we do here.
+  if (mFuzzLocation)
+  {
+    // need to make a copy because nsIDOMGeolocation is
+    // readonly, and we are not sure of its implementation.
+
+    double lat, lon, alt, herror, verror;
+    DOMTimeStamp time;
+    location->GetLatitude(&lat);
+    location->GetLongitude(&lon);
+    location->GetAltitude(&alt);
+    location->GetHorizontalAccuracy(&herror);
+    location->GetVerticalAccuracy(&verror);
+    location->GetTimestamp(&time); 
+
+    // do something to the numbers...  TODO.
+    
+    // mask out any location until we figure out how to fuzz locations;
+    lat = 0; lon = 0; alt = 0; herror = 100000; verror = 100000;
+
+    nsRefPtr<nsGeolocation> somewhere = new nsGeolocation(lat,
+                                                          lon,
+                                                          alt,
+                                                          herror,
+                                                          verror,
+                                                          time);
+    mCallback->OnRequest(somewhere);
+    return;
+  }
+  
+  mCallback->OnRequest(location);
+}
+
+void
+nsGeolocationRequest::Shutdown()
+{
+  mCleared = PR_TRUE;
+  mCallback = nsnull;
+}
+
+////////////////////////////////////////////////////
+// nsGeolocation
+////////////////////////////////////////////////////
+NS_INTERFACE_MAP_BEGIN(nsGeolocation)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeolocation)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMGeolocation)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Geolocation)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_THREADSAFE_ADDREF(nsGeolocation)
+NS_IMPL_THREADSAFE_RELEASE(nsGeolocation)
+
+NS_IMETHODIMP
+nsGeolocation::GetLatitude(double *aLatitude)
+{
+  *aLatitude = mLat;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocation::GetLongitude(double *aLongitude)
+{
+  *aLongitude = mLong;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocation::GetAltitude(double *aAltitude)
+{
+  *aAltitude = mAlt;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocation::GetHorizontalAccuracy(double *aHorizontalAccuracy)
+{
+  *aHorizontalAccuracy = mHError;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocation::GetVerticalAccuracy(double *aVerticalAccuracy)
+{
+  *aVerticalAccuracy = mVError;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocation::GetTimestamp(DOMTimeStamp* aTimestamp)
+{
+  *aTimestamp = mTimestamp;
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////
+// nsGeolocatorService
+////////////////////////////////////////////////////
+NS_INTERFACE_MAP_BEGIN(nsGeolocatorService)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGeolocationUpdate)
+  NS_INTERFACE_MAP_ENTRY(nsIGeolocationUpdate)
+  NS_INTERFACE_MAP_ENTRY(nsIGeolocationService)
+  NS_INTERFACE_MAP_ENTRY(nsIObserver)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_THREADSAFE_ADDREF(nsGeolocatorService)
+NS_IMPL_THREADSAFE_RELEASE(nsGeolocatorService)
+
+nsGeolocatorService::nsGeolocatorService()
+{
+  nsCOMPtr<nsIObserverService> obs = do_GetService("@mozilla.org/observer-service;1");
+  if (obs) {
+    obs->AddObserver(this, "quit-application", false);
+  }
+
+  mTimeout = nsContentUtils::GetIntPref("geo.timeout", 6000);
+}
+
+nsGeolocatorService::~nsGeolocatorService()
+{
+}
+
+NS_IMETHODIMP
+nsGeolocatorService::Observe(nsISupports* aSubject, const char* aTopic,
+                             const PRUnichar* aData)
+{
+  if (!strcmp("quit-application", aTopic))
+  {
+    nsCOMPtr<nsIObserverService> obs = do_GetService("@mozilla.org/observer-service;1");
+    if (obs) {
+      obs->RemoveObserver(this, "quit-application");
+    }
+
+    for (PRUint32 i = 0; i< mGeolocators.Length(); i++)
+      mGeolocators[i]->Shutdown();
+
+    StopDevice();
+
+    // Remove our reference to any prompt that may have been set.
+    mPrompt = nsnull;
+    return NS_OK;
+  }
+  
+  if (!strcmp("timer-callback", aTopic))
+  {
+    // decide if we can close down the service.
+    for (PRUint32 i = 0; i< mGeolocators.Length(); i++)
+      if (mGeolocators[i]->HasActiveCallbacks())
+      {
+        SetDisconnectTimer();
+        return NS_OK;
+      }
+    
+    // okay to close up.
+    StopDevice();
+    Update(nsnull);
+    return NS_OK;
+  }
+
+  return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsGeolocatorService::GetPrompt(nsIGeolocationPrompt * *aPrompt)
+{
+  NS_ENSURE_ARG_POINTER(aPrompt);
+  *aPrompt = mPrompt;
+  NS_IF_ADDREF(*aPrompt);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocatorService::SetPrompt(nsIGeolocationPrompt * aPrompt)
+{
+  mPrompt = aPrompt;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocatorService::Update(nsIDOMGeolocation *somewhere)
+{
+  for (PRUint32 i = 0; i< mGeolocators.Length(); i++)
+    mGeolocators[i]->Update(somewhere);
+  return NS_OK;
+}
+
+already_AddRefed<nsIDOMGeolocation>
+nsGeolocatorService::GetLastKnownPosition()
+{
+  nsIDOMGeolocation* location = nsnull;
+  if (mProvider)
+    mProvider->GetCurrentLocation(&location);
+
+  return location;
+}
+
+PRBool
+nsGeolocatorService::IsDeviceReady()
+{
+  PRBool ready = PR_FALSE;
+  if (mProvider)
+    mProvider->IsReady(&ready);
+
+  return ready;
+}
+
+nsresult
+nsGeolocatorService::StartDevice()
+{
+  if (!mProvider)
+  {
+    // Check to see if there is an override in place. if so, use it.
+    mProvider = do_GetService(NS_GEOLOCATION_PROVIDER_CONTRACTID);
+
+    // if NS_OSSO, see if we should try the MAEMO location provider
+#ifdef NS_OSSO
+    if (!mProvider)
+    {
+      // guess not, lets try a default one:  
+      mProvider = new MaemoLocationProvider();
+    }
+#endif
+
+    if (!mProvider)
+      return NS_ERROR_NOT_AVAILABLE;
+    
+    // if we have one, start it up.
+    nsresult rv = mProvider->Startup();
+    if (NS_FAILED(rv)) 
+      return NS_ERROR_NOT_AVAILABLE;;
+    
+    // lets monitor it for any changes.
+    mProvider->Watch(this);
+    
+    // we do not want to keep the geolocation devices online
+    // indefinitely.  Close them down after a reasonable period of
+    // inactivivity
+    SetDisconnectTimer();
+  }
+
+  return NS_OK;
+}
+
+void
+nsGeolocatorService::SetDisconnectTimer()
+{
+  if (!mDisconnectTimer)
+    mDisconnectTimer = do_CreateInstance("@mozilla.org/timer;1");
+  else
+    mDisconnectTimer->Cancel();
+
+  mDisconnectTimer->Init(this,
+                         mTimeout,
+                         nsITimer::TYPE_ONE_SHOT);
+}
+
+void 
+nsGeolocatorService::StopDevice()
+{
+  if (mProvider) {
+    mProvider->Shutdown();
+    mProvider = nsnull;
+  }
+
+  if(mDisconnectTimer) {
+    mDisconnectTimer->Cancel();
+    mDisconnectTimer = nsnull;
+  }
+}
+
+nsGeolocatorService* nsGeolocatorService::gService = nsnull;
+
+nsGeolocatorService*
+nsGeolocatorService::GetInstance()
+{
+  if (!nsGeolocatorService::gService) {
+    nsGeolocatorService::gService = new nsGeolocatorService();
+  }
+  return nsGeolocatorService::gService;
+}
+
+nsGeolocatorService*
+nsGeolocatorService::GetGeolocationService()
+{
+  nsGeolocatorService* inst = nsGeolocatorService::GetInstance();
+  NS_ADDREF(inst);
+  return inst;
+}
+
+void
+nsGeolocatorService::AddLocator(nsGeolocator* locator)
+{
+  mGeolocators.AppendElement(locator);
+}
+
+void
+nsGeolocatorService::RemoveLocator(nsGeolocator* locator)
+{
+  mGeolocators.RemoveElement(locator);
+}
+
+////////////////////////////////////////////////////
+// nsGeolocator
+////////////////////////////////////////////////////
+
+NS_INTERFACE_MAP_BEGIN(nsGeolocator)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeolocator)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMGeolocator)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Geolocator)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(nsGeolocator)
+NS_IMPL_RELEASE(nsGeolocator)
+
+nsGeolocator::nsGeolocator(nsIDOMWindow* contentDom) 
+: mUpdateInProgress(PR_FALSE)
+{
+  // Remember the window
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(contentDom);
+  if (window)
+    mOwner = window->GetCurrentInnerWindow();
+
+  // Grab the uri of the document
+  nsCOMPtr<nsIDOMDocument> domdoc;
+  contentDom->GetDocument(getter_AddRefs(domdoc));
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
+  if (doc)
+    doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
+
+  mService = nsGeolocatorService::GetInstance();
+  if (mService)
+    mService->AddLocator(this);
+}
+
+nsGeolocator::~nsGeolocator()
+{
+}
+
+void
+nsGeolocator::Shutdown()
+{
+  // Shutdown and release all callbacks
+  for (PRInt32 i = 0; i< mPendingCallbacks.Count(); i++)
+    mPendingCallbacks[i]->Shutdown();
+  mPendingCallbacks.Clear();
+
+  for (PRInt32 i = 0; i< mWatchingCallbacks.Count(); i++)
+    mWatchingCallbacks[i]->Shutdown();
+  mWatchingCallbacks.Clear();
+
+  if (mService)
+    mService->RemoveLocator(this);
+
+  mService = nsnull;
+  mOwner = nsnull;
+  mURI = nsnull;
+}
+
+PRBool
+nsGeolocator::HasActiveCallbacks()
+{
+  return (PRBool) mWatchingCallbacks.Count();
+}
+
+void
+nsGeolocator::RemoveRequest(nsGeolocationRequest* request)
+{
+  mPendingCallbacks.RemoveObject(request);
+
+  // if it is in the mWatchingCallbacks, we can't do much
+  // since we passed back the position in the array to who
+  // ever called WatchPosition() and we do not want to mess
+  // around with the ordering of the array.  Instead, just
+  // mark the request as "cleared".
+
+  request->MarkCleared();
+}
+
+void
+nsGeolocator::Update(nsIDOMGeolocation *somewhere)
+{
+  // This method calls out to objects which may spin and
+  // event loop which may add new location objects into
+  // mPendingCallbacks, and mWatchingCallbacks.  Since this
+  // function can only be called on the primary thread, we
+  // can lock this method with a member var.
+
+  if (mUpdateInProgress)
+    return;
+
+  mUpdateInProgress = PR_TRUE;
+  if (!OwnerStillExists())
+  {
+    Shutdown();
+    return;
+  }
+
+  // notify anyone that has been waiting
+  for (PRInt32 i = 0; i< mPendingCallbacks.Count(); i++)
+    mPendingCallbacks[i]->SendLocation(somewhere);
+  mPendingCallbacks.Clear();
+
+  // notify everyone that is watching
+  for (PRInt32 i = 0; i< mWatchingCallbacks.Count(); i++)
+      mWatchingCallbacks[i]->SendLocation(somewhere);
+
+  mUpdateInProgress = PR_FALSE;
+}
+
+NS_IMETHODIMP
+nsGeolocator::GetLastPosition(nsIDOMGeolocation * *aLastPosition)
+{
+  // we are advocating that this method be removed.
+  NS_ENSURE_ARG_POINTER(aLastPosition);
+  *aLastPosition = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocator::GetCurrentPosition(nsIDOMGeolocationCallback *callback)
+{
+  nsIGeolocationPrompt* prompt = mService->GetPrompt();
+  if (prompt == nsnull)
+    return NS_ERROR_NOT_AVAILABLE;
+
+  nsRefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this, callback);
+  prompt->Prompt(request);
+
+  // What if you have a location provider that only sends a location once, then stops.?  fix.
+  mPendingCallbacks.AppendObject(request);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocator::WatchPosition(nsIDOMGeolocationCallback *callback, PRUint16 *_retval NS_OUTPARAM)
+{
+  nsIGeolocationPrompt* prompt = mService->GetPrompt();
+  if (prompt == nsnull)
+    return NS_ERROR_NOT_AVAILABLE;
+    
+  nsRefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this, callback);
+  prompt->Prompt(request);
+
+  // need to hand back an index/reference.
+  mWatchingCallbacks.AppendObject(request);
+  *_retval = mWatchingCallbacks.Count() - 1;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeolocator::ClearWatch(PRUint16 watchId)
+{
+  mWatchingCallbacks[watchId]->MarkCleared();
+  return NS_OK;
+}
+
+PRBool
+nsGeolocator::OwnerStillExists()
+{
+  if (!mOwner)
+    return PR_FALSE;
+
+  nsCOMPtr<nsIDOMWindowInternal> domWindow(mOwner);
+  if (domWindow)
+  {
+    PRBool closed = PR_FALSE;
+    domWindow->GetClosed(&closed);
+    if (closed)
+      return PR_FALSE;
+  }
+
+  nsPIDOMWindow* outer = mOwner->GetOuterWindow();
+  if (!outer || outer->GetCurrentInnerWindow() != mOwner)
+    return PR_FALSE;
+
+  return PR_TRUE;
+}
new file mode 100644
--- /dev/null
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -0,0 +1,224 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Geolocation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Doug Turner <dougt@meer.net>  (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
+#include "nsCOMArray.h"
+#include "nsTArray.h"
+#include "nsITimer.h"
+#include "nsIObserver.h"
+#include "nsIURI.h"
+
+#include "nsIDOMGeolocation.h"
+#include "nsIDOMGeolocation.h"
+#include "nsIDOMGeolocationCallback.h"
+#include "nsIDOMGeolocator.h"
+#include "nsIDOMNavigatorGeolocator.h"
+
+#include "nsPIDOMWindow.h"
+
+#include "nsIGeolocationProvider.h"
+
+class nsGeolocator;
+class nsGeolocatorService;
+
+
+class nsGeolocationRequest : public nsIGeolocationRequest
+{
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIGEOLOCATIONREQUEST
+
+  nsGeolocationRequest(nsGeolocator* locator, nsIDOMGeolocationCallback* callback);
+  void Shutdown();
+
+  void SendLocation(nsIDOMGeolocation* location);
+  void MarkCleared();
+  PRBool Allowed() {return mAllowed;}
+
+  ~nsGeolocationRequest();
+
+ private:
+  PRBool mAllowed;
+  PRBool mCleared;
+  PRBool mFuzzLocation;
+
+  nsCOMPtr<nsIDOMGeolocationCallback> mCallback;
+
+  nsGeolocator* mLocator; // The locator exists alonger than this object.
+};
+
+/**
+ * Simple object that holds a single point in space.
+ */ 
+class nsGeolocation : public nsIDOMGeolocation
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOMGEOLOCATION
+
+    nsGeolocation(double aLat, double aLong, double aAlt, double aHError, double aVError, long long aTimestamp)
+    : mLat(aLat), mLong(aLong), mAlt(aAlt), mHError(aHError), mVError(aVError), mTimestamp(aTimestamp){};
+
+private:
+  ~nsGeolocation(){}
+  double mLat, mLong, mAlt, mHError, mVError;
+  long long mTimestamp;
+};
+
+/**
+ * Singleton that manages the geolocation provider
+ */
+class nsGeolocatorService : public nsIGeolocationService, public nsIGeolocationUpdate, public nsIObserver
+{
+public:
+
+  static nsGeolocatorService* GetGeolocationService();
+  static nsGeolocatorService* GetInstance();  // Non-Addref'ing
+  static nsGeolocatorService* gService;
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIGEOLOCATIONUPDATE
+  NS_DECL_NSIOBSERVER
+  NS_DECL_NSIGEOLOCATIONSERVICE
+
+  nsGeolocatorService();
+
+  // Management of the nsGeolocator objects
+  void AddLocator(nsGeolocator* locator);
+  void RemoveLocator(nsGeolocator* locator);
+
+  // Returns the last geolocation we have seen since calling StartDevice()
+  already_AddRefed<nsIDOMGeolocation> GetLastKnownPosition();
+  
+  // Returns the application defined UI prompt
+  nsIGeolocationPrompt* GetPrompt() { return mPrompt; } // does not addref.
+
+  // Returns true if the we have successfully found and started a
+  // geolocation device
+  PRBool   IsDeviceReady();
+
+  // Find and startup a geolocation device (gps, nmea, etc.)
+  nsresult StartDevice();
+
+  // Stop the started geolocation device (gps, nmea, etc.)
+  void     StopDevice();
+  
+  // create, or reinitalize the callback timer
+  void     SetDisconnectTimer();
+
+private:
+
+  ~nsGeolocatorService();
+
+  // Disconnect timer.  When this timer expires, it clears all pending callbacks
+  // and closes down the provider, unless we are watching a point, and in that
+  // case, we disable the disconnect timer.
+  nsCOMPtr<nsITimer> mDisconnectTimer;
+
+  // Time, in milliseconds, to wait for the location provider to spin up.
+  PRInt32 mTimeout;
+
+  // The object providing geo location information to us.
+  nsCOMPtr<nsIGeolocationProvider> mProvider;
+
+  // mGeolocators are not owned here.  Their constructor
+  // addes them to this list, and their destructor removes
+  // them from this list.
+  nsTArray<nsGeolocator*> mGeolocators;
+
+  // prompt callback, if any
+  nsCOMPtr<nsIGeolocationPrompt> mPrompt;
+};
+
+
+/**
+ * Can return a geolocation info
+ */ 
+class nsGeolocator : public nsIDOMGeolocator
+{
+public:
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOMGEOLOCATOR
+
+  nsGeolocator(nsIDOMWindow* contentDom);
+
+  // Called by the geolocation device to notify that a location has changed.
+  void Update(nsIDOMGeolocation* aLocation);
+
+  // Returns true if any of the callbacks are repeating
+  PRBool   HasActiveCallbacks();
+
+  // Remove request from all callbacks arrays
+  void     RemoveRequest(nsGeolocationRequest* request);
+
+  // Shutting down.
+  void     Shutdown();
+
+  // Setter and Getter of the URI that this nsGeolocator was loaded from
+  nsIURI* GetURI() { return mURI; }
+
+  // Setter and Getter of the window that this nsGeolocator is owned by
+  nsIDOMWindow* GetOwner() { return mOwner; }
+
+  // Check to see if the widnow still exists
+  PRBool OwnerStillExists();
+
+private:
+
+  ~nsGeolocator();
+
+  // Two callback arrays.  The first |mPendingCallbacks| holds objects for only
+  // one callback and then they are released/removed from the array.  The second
+  // |mWatchingCallbacks| holds objects until the object is explictly removed or
+  // there is a page change.
+
+  nsCOMArray<nsGeolocationRequest> mPendingCallbacks;
+  nsCOMArray<nsGeolocationRequest> mWatchingCallbacks;
+
+  PRBool mUpdateInProgress;
+
+  // window that this was created for.  Weak reference.
+  nsPIDOMWindow* mOwner;
+
+  // where the content was loaded from
+  nsCOMPtr<nsIURI> mURI;
+
+  // owning back pointer.
+  nsRefPtr<nsGeolocatorService> mService;
+};
--- a/dom/tests/mochitest/Makefile.in
+++ b/dom/tests/mochitest/Makefile.in
@@ -45,16 +45,17 @@ include $(DEPTH)/config/autoconf.mk
 DIRS	+= \
 	dom-level0 \
 	dom-level1-core \
 	dom-level2-core \
 	ajax \
 	bugs \
 	chrome \
 	whatwg \
+	geolocation \
 	$(NULL)
 
 # dom-level2-html disabled due to failures on multiple platforms
 # (bug 427878)
 #	dom-level2-html \
 
 include $(topsrcdir)/config/rules.mk
 
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/Makefile.in
@@ -0,0 +1,58 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org build system.
+#
+# The Initial Developer of the Original Code is Mozilla Corporation
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Doug Turner <dougt@meer.net>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir	= dom/tests/mochitest/geolocation
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES	= \
+		test_lastPosition.html \
+		test_manyWindows.html \
+		prompt_common.js       \
+		geolocation_common.js  \
+		geolocator.html \
+		$(NULL)
+
+
+libs:: 	$(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/geolocation_common.js
@@ -0,0 +1,12 @@
+function check_geolocation(location) {
+
+  ok(location, "Check to see if this location is non-null");
+
+  ok(location.latitude, "Check to see if there is a latitude");
+  ok(location.longitude, "Check to see if there is a longitude");
+  ok(location.altitude, "Check to see if there is a altitude");
+  ok(location.horizontalAccuracy, "Check to see if there is a horizontalAccuracy");
+  ok(location.verticalAccuracy, "Check to see if there is a verticalAccuracy");
+  ok(location.timestamp, "Check to see if there is a timestamp");
+
+}
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/geolocator.html
@@ -0,0 +1,12 @@
+<html> <head>
+<title>Simple access of geolocator</title>
+<script>
+
+document.writeln(navigator.geolocator);
+
+</script>
+</head>
+<body>
+<p>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/prompt_common.js
@@ -0,0 +1,75 @@
+netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+
+const Ci = Components.interfaces;
+ok(Ci != null, "Access Ci");
+const Cc = Components.classes;
+ok(Cc != null, "Access Cc");
+
+var didDialog;
+
+var timer; // keep in outer scope so it's not GC'd before firing
+function startCallbackTimer() {
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+    didDialog = false;
+
+    // Delay before the callback twiddles the prompt.
+    const dialogDelay = 10;
+
+    // Use a timer to invoke a callback to twiddle the authentication dialog
+    timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
+}
+
+var observer = {
+    QueryInterface : function (iid) {
+        const interfaces = [Ci.nsIObserver,
+                            Ci.nsISupports, Ci.nsISupportsWeakReference];
+
+        if (!interfaces.some( function(v) { return iid.equals(v) } ))
+            throw Components.results.NS_ERROR_NO_INTERFACE;
+        return this;
+    },
+
+    observe : function (subject, topic, data) {
+        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+
+        var doc = getDialogDoc();
+        if (doc)
+            handleDialog(doc);
+        else
+            startCallbackTimer(); // try again in a bit
+    }
+};
+
+function getDialogDoc() {
+    // Find the <browser> which contains notifyWindow, by looking
+    // through all the open windows and all the <browsers> in each.
+  var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+      getService(Ci.nsIWindowMediator);
+  //var enumerator = wm.getEnumerator("navigator:browser");
+  var enumerator = wm.getXULWindowEnumerator(null);
+
+  while (enumerator.hasMoreElements()) {
+      var win = enumerator.getNext();
+      var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
+
+      var containedDocShells = windowDocShell.getDocShellEnumerator(
+                                                                    Ci.nsIDocShellTreeItem.typeChrome,
+                                                                    Ci.nsIDocShell.ENUMERATE_FORWARDS);
+      while (containedDocShells.hasMoreElements()) {
+          // Get the corresponding document for this docshell
+          var childDocShell = containedDocShells.getNext();
+          // We don't want it if it's not done loading.
+          if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
+              continue;
+          var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell).
+              contentViewer.DOMDocument;
+
+          //ok(true, "Got window: " + childDoc.location.href);
+          if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
+              return childDoc;
+      }
+  }
+
+  return null;
+}
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/test_lastPosition.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=
+-->
+<head>
+  <title>Test for getCurrentPosition </title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="prompt_common.js"></script>
+  <script type="text/javascript" src="geolocation_common.js"></script>
+
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug  **/
+
+
+function handleDialog(doc) {
+  // Verify the error message is correct - the string (places) is not
+  // translated
+
+  var dialog = doc.getElementById("commonDialog");
+  var desc = doc.getElementById("info.body");
+  var errmsg = desc.childNodes[0].data;
+
+  ok(errmsg.indexOf("located") > 0, "Check for the correct message");
+
+  // Clear the dialog
+  if (allow_dialog)
+    dialog.acceptDialog();
+  else
+    dialog.cancelDialog();
+}
+
+
+
+ok(navigator.geolocator, "Ensure that the geolocation object is present");
+
+//first we want to prevent this proprerty from loading.
+/*
+Moving to the info bar very soon.  right now, there is no
+dialog in FF.  
+
+  allow_dialog = 0;
+  startCallbackTimer();
+*/
+
+last = navigator.geolocator.lastPosition;
+
+ok(last == null, "Check to ensure the lastPosition is null");
+
+// Try again, but this time allow the lookup.
+/*
+Moving to the info bar very soon.  right now, there is no
+dialog in FF
+
+allow_dialog = 1;
+startCallbackTimer();
+*/
+
+last = navigator.geolocator.lastPosition;
+
+if (last != null) {
+  check_geolocation(last);
+}
+else
+{
+  ok(1, "No geo location available");
+}
+
+SimpleTest.finish();
+
+
+
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/geolocation/test_manyWindows.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=
+-->
+<head>
+  <title>Test for many windows </title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="prompt_common.js"></script>
+  <script type="text/javascript" src="geolocation_common.js"></script>
+
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank"
+href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Crash in Multiple Windows</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug  **/
+
+ok(navigator.geolocator, "Ensure that the geolocation object is present");
+
+var numberOfWindows = 20;  // 20 seems to be the default max popups during the mochitest run
+var totalWindows = numberOfWindows;
+
+var windows = new Array(numberOfWindows);
+
+for(var i = 0; i < numberOfWindows; i++) {
+  windows[i] = window.open("geolocator.html", "_blank", "width=700,height=400");
+}
+
+for(var i = 0; i < numberOfWindows; i++) {
+  windows[i].close();
+  totalWindows --;
+}
+
+function checkDone()
+{
+    if (totalWindows == 0)
+    {
+        ok(navigator.geolocator, "Opened a bunch of windows and didn't crash.");
+        clearInterval(timer);
+        SimpleTest.finish();
+    }
+}
+
+var timer = setInterval(checkDone, 1000);
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -133,16 +133,17 @@ SHARED_LIBRARY_LIBS = \
 	$(DEPTH)/content/xul/document/src/$(LIB_PREFIX)gkconxuldoc_s.$(LIB_SUFFIX) \
 	$(DEPTH)/view/src/$(LIB_PREFIX)gkview_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/base/$(LIB_PREFIX)jsdombase_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/events/$(LIB_PREFIX)jsdomevents_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/json/$(LIB_PREFIX)json_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/jsurl/$(LIB_PREFIX)jsurl_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/storage/$(LIB_PREFIX)jsdomstorage_s.$(LIB_SUFFIX) \
 	$(DEPTH)/dom/src/offline/$(LIB_PREFIX)jsdomoffline_s.$(LIB_SUFFIX) \
+ 	$(DEPTH)/dom/src/geolocation/$(LIB_PREFIX)jsdomgeolocation_s.$(LIB_SUFFIX) \
 	$(DEPTH)/editor/libeditor/text/$(LIB_PREFIX)texteditor_s.$(LIB_SUFFIX) \
 	$(DEPTH)/editor/libeditor/base/$(LIB_PREFIX)editorbase_s.$(LIB_SUFFIX) \
 	$(NULL)
 
 ifdef MOZ_MEDIA
 SHARED_LIBRARY_LIBS 	+= \
 	$(DEPTH)/content/media/video/src/$(LIB_PREFIX)gkconvideo_s.$(LIB_SUFFIX) \
 	$(NULL)
@@ -262,16 +263,17 @@ LOCAL_INCLUDES	+= -I$(srcdir)/../base \
 		   -I$(topsrcdir)/content/events/src \
 		   -I$(topsrcdir)/content/xbl/src \
 		   -I$(topsrcdir)/view/src \
 		   -I$(topsrcdir)/dom/src/base \
 		   -I$(topsrcdir)/dom/src/json \
 		   -I$(topsrcdir)/dom/src/jsurl \
 		   -I$(topsrcdir)/dom/src/storage \
 		   -I$(topsrcdir)/dom/src/offline \
+		   -I$(topsrcdir)/dom/src/geolocation \
 		   -I. \
 		   -I$(topsrcdir)/editor/libeditor/base \
 		   -I$(topsrcdir)/editor/libeditor/text \
 		   -I$(topsrcdir)/editor/libeditor/html \
 		   -I$(topsrcdir)/editor/txtsvc/src \
 		   -I$(topsrcdir)/editor/composer/src \
 		   $(NULL)
 
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -261,16 +261,18 @@ NS_NewXULTreeBuilder(nsISupports* aOuter
 PR_STATIC_CALLBACK(nsresult) Initialize(nsIModule* aSelf);
 static void Shutdown();
 
 #ifdef MOZ_XTF
 #include "nsIXTFService.h"
 #include "nsIXMLContentBuilder.h"
 #endif
 
+#include "nsGeolocation.h"
+
 // Transformiix
 /* {0C351177-0159-4500-86B0-A219DFDE4258} */
 #define TRANSFORMIIX_XPATH1_SCHEME_CID \
 { 0xc351177, 0x159, 0x4500, { 0x86, 0xb0, 0xa2, 0x19, 0xdf, 0xde, 0x42, 0x58 } }
 
 /* 5d5d92cd-6bf8-11d9-bf4a-000a95dc234c */
 #define TRANSFORMIIX_NODESET_CID \
 { 0x5d5d92cd, 0x6bf8, 0x11d9, { 0xbf, 0x4a, 0x0, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
@@ -781,16 +783,21 @@ CreateWindowControllerWithSingletonComma
   if (NS_FAILED(rv)) return rv;
 
   return controller->QueryInterface(aIID, aResult);
 }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMScriptObjectFactory)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBaseDOMException)
 
+#define NS_GEOLOCATION_SERVICE_CID \
+  { 0x404d02a, 0x1CA, 0xAAAB, { 0x47, 0x62, 0x94, 0x4b, 0x1b, 0xf2, 0xf7, 0xb5 } }
+
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsGeolocatorService, nsGeolocatorService::GetGeolocationService)
+
 // The list of components we register
 static const nsModuleComponentInfo gComponents[] = {
 #ifdef DEBUG
   { "Frame utility",
     NS_FRAME_UTIL_CID,
     nsnull,
     CreateNewFrameUtil },
   { "Layout debugger",
@@ -1368,11 +1375,18 @@ static const nsModuleComponentInfo gComp
       nsEditorCommandTableConstructor },
 
 #ifndef MOZILLA_PLAINTEXT_EDITOR_ONLY
     { NULL,
       NS_TEXTSERVICESDOCUMENT_CID,
       "@mozilla.org/textservices/textservicesdocument;1",
       nsTextServicesDocumentConstructor },
 #endif
+
+    { "Geolocation Service",
+      NS_GEOLOCATION_SERVICE_CID,
+      "@mozilla.org/geolocation/service;1",
+      nsGeolocatorServiceConstructor },
+
+
 };
 
 NS_IMPL_NSGETMODULE_WITH_CTOR(nsLayoutModule, gComponents, Initialize)
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -207,16 +207,20 @@ EXTRA_DSO_LDOPTS += \
 	$(NULL)
 endif
 
 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(MOZ_XFT_LIBS) $(MOZ_GTK2_LIBS) $(XT_LIBS) -lgthread-2.0
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
+ifdef NS_OSSO
+EXTRA_DSO_LDOPTS += -llocation -lgpsbt
+endif
+
 ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
 EXTRA_DSO_LDOPTS += $(MOZ_STARTUP_NOTIFICATION_LIBS)
 endif
 
 ifeq ($(OS_ARCH),BeOS)
 EXTRA_DSO_LDOPTS += -lbe -ltracker
 endif