Backout 8b74d5ae78c3 & c619bbb2951f (bug 734391), 772c994fa869 (bug 734324), fd23ff0f9dd1 (bug 734325), d1e037a9390e (bug 733653), 3a7bf79b5b2d (bug 733650) & 9d9392fce538 (bug 733652) for OS X M1 & M3 orange
authorEd Morley <bmo@edmorley.co.uk>
Tue, 13 Mar 2012 22:29:29 +0000
changeset 92293 ec55dae77b79ba6b413b44ae0a4bb362d1ac4dfd
parent 92292 2485d40bdbe5b6ae61c67e5e32067dc37c460841
child 92294 13d65ef93dc53cf068f537c2e8568ec236bc10fb
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs734391, 734324, 734325, 733653, 733650, 733652
milestone14.0a1
backs out8b74d5ae78c3bbd92a25a93199122331a0dcab1f
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout 8b74d5ae78c3 & c619bbb2951f (bug 734391), 772c994fa869 (bug 734324), fd23ff0f9dd1 (bug 734325), d1e037a9390e (bug 733653), 3a7bf79b5b2d (bug 733650) & 9d9392fce538 (bug 733652) for OS X M1 & M3 orange
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/interfaces/geolocation/Makefile.in
dom/interfaces/geolocation/nsIDOMGeoPosition.idl
dom/interfaces/geolocation/nsIDOMGeoPositionAddress.idl
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/PContent.ipdl
dom/src/geolocation/nsGeoPosition.cpp
dom/src/geolocation/nsGeoPosition.h
dom/src/geolocation/nsGeoPositionIPCSerialiser.h
dom/system/Makefile.in
dom/system/android/Makefile.in
dom/system/cocoa/Makefile.in
dom/system/cocoa/nsDeviceMotionSystem.mm
dom/system/cocoa/smslib.h
dom/system/cocoa/smslib.mm
dom/system/nsDeviceMotion.cpp
dom/system/nsDeviceMotion.h
dom/system/unix/Makefile.in
dom/system/unix/nsDeviceMotionSystem.cpp
dom/system/windows/Makefile.in
dom/system/windows/nsDeviceMotionSystem.cpp
embedding/android/GeckoEvent.java
embedding/android/GeckoSurfaceView.java
hal/HalSensor.h
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoEvent.java
mobile/android/base/GeckoHalDefines.java
mobile/android/base/Makefile.in
toolkit/content/license.html
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJavaWrappers.cpp
widget/android/AndroidJavaWrappers.h
widget/android/nsAppShell.cpp
widget/android/nsAppShell.h
xpcom/system/nsIDeviceMotion.idl
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1417,16 +1417,19 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   
   NS_DEFINE_CLASSINFO_DATA(GeoPosition, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS) 
   
   NS_DEFINE_CLASSINFO_DATA(GeoPositionCoords, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
+  NS_DEFINE_CLASSINFO_DATA(GeoPositionAddress, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozBatteryManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozPowerManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -4012,16 +4015,20 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(GeoPosition, nsIDOMGeoPosition)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPosition)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(GeoPositionCoords, nsIDOMGeoPositionCoords)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionCoords)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(GeoPositionAddress, nsIDOMGeoPositionAddress)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionAddress)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(GeoPositionError, nsIDOMGeoPositionError)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozBatteryManager, nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -417,16 +417,17 @@ DOMCI_CLASS(DataContainerEvent)
 // event used for cross-domain message-passing and for server-sent events in
 // HTML5
 DOMCI_CLASS(MessageEvent)
 
 // Geolocation
 DOMCI_CLASS(GeoGeolocation)
 DOMCI_CLASS(GeoPosition)
 DOMCI_CLASS(GeoPositionCoords)
+DOMCI_CLASS(GeoPositionAddress)
 DOMCI_CLASS(GeoPositionError)
 
 DOMCI_CLASS(MozBatteryManager)
 
 DOMCI_CLASS(MozPowerManager)
 DOMCI_CLASS(MozWakeLock)
 
 DOMCI_CLASS(MozSmsManager)
--- a/dom/interfaces/geolocation/Makefile.in
+++ b/dom/interfaces/geolocation/Makefile.in
@@ -44,16 +44,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE         = dom
 XPIDL_MODULE   = dom_geolocation
 GRE_MODULE     = 1
 
 XPIDLSRCS =                                    \
             nsIDOMGeoGeolocation.idl           \
             nsIDOMGeoPosition.idl              \
+            nsIDOMGeoPositionAddress.idl       \
             nsIDOMGeoPositionCoords.idl        \
             nsIDOMGeoPositionCallback.idl      \
             nsIDOMGeoPositionError.idl         \
             nsIDOMGeoPositionErrorCallback.idl \
             nsIDOMGeoPositionOptions.idl       \
             nsIDOMNavigatorGeolocation.idl     \
             $(NULL)
 
--- a/dom/interfaces/geolocation/nsIDOMGeoPosition.idl
+++ b/dom/interfaces/geolocation/nsIDOMGeoPosition.idl
@@ -32,15 +32,18 @@
  * 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"
 #include "nsIDOMGeoPositionCoords.idl"
+#include "nsIDOMGeoPositionAddress.idl"
 
-[scriptable, uuid(dd9f7e81-0f74-4fb5-b361-37019bf60c3f)]
+[scriptable, uuid(23E5269F-4DD7-41C4-B52A-75918694C2DE)]
 interface nsIDOMGeoPosition : nsISupports
 {
   readonly attribute DOMTimeStamp timestamp;
   readonly attribute nsIDOMGeoPositionCoords coords;
+  readonly attribute nsIDOMGeoPositionAddress address;
+
 };
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/geolocation/nsIDOMGeoPositionAddress.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 Foundation
+ * 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(93abae10-7024-49eb-8e05-1931343b0ebb)]
+interface nsIDOMGeoPositionAddress : nsISupports
+{
+  readonly attribute DOMString streetNumber;
+  readonly attribute DOMString street;
+  readonly attribute DOMString premises;
+  readonly attribute DOMString city;
+  readonly attribute DOMString county;
+  readonly attribute DOMString region;
+  readonly attribute DOMString country;
+  readonly attribute DOMString postalCode;
+};
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -749,26 +749,16 @@ ContentChild::RecvDeviceMotionChanged(co
     nsCOMPtr<nsIDeviceMotionUpdate> dmu = 
         do_GetService(NS_DEVICE_MOTION_CONTRACTID);
     if (dmu)
         dmu->DeviceMotionChanged(type, x, y, z);
     return true;
 }
 
 bool
-ContentChild::RecvNeedsCalibration()
-{
-    nsCOMPtr<nsIDeviceMotionUpdate> dmu = 
-        do_GetService(NS_DEVICE_MOTION_CONTRACTID);
-    if (dmu)
-        dmu->NeedsCalibration();
-    return true;
-}
-
-bool
 ContentChild::RecvScreenSizeChanged(const gfxIntSize& size)
 {
 #ifdef ANDROID
     mScreenSize = size;
 #else
     NS_RUNTIMEABORT("Message currently only expected on android");
 #endif
   return true;
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -157,18 +157,16 @@ public:
     virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
 
     virtual bool RecvAddPermission(const IPC::Permission& permission);
 
     virtual bool RecvDeviceMotionChanged(const long int& type,
                                          const double& x, const double& y,
                                          const double& z);
 
-    virtual bool RecvNeedsCalibration();
-
     virtual bool RecvScreenSizeChanged(const gfxIntSize &size);
 
     virtual bool RecvFlushMemory(const nsString& reason);
 
     virtual bool RecvActivateA11y();
 
     virtual bool RecvGarbageCollect();
     virtual bool RecvCycleCollect();
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1286,17 +1286,11 @@ ContentParent::OnMotionChange(nsIDeviceM
     aDeviceData->GetX(&x);
     aDeviceData->GetY(&y);
     aDeviceData->GetZ(&z);
 
     unused << SendDeviceMotionChanged(type, x, y, z);
     return NS_OK;
 }
 
-NS_IMETHODIMP
-ContentParent::NeedsCalibration() {
-    unused << SendNeedsCalibration();
-    return NS_OK;
-}
-
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -129,17 +129,16 @@ child:
     NotifyAlertsObserver(nsCString topic, nsString data);
 
     GeolocationUpdate(GeoPosition somewhere);
 
     // nsIPermissionManager messages
     AddPermission(Permission permission);
 
     DeviceMotionChanged(long type, double x, double y, double z);
-    NeedsCalibration();
 
     ScreenSizeChanged(gfxIntSize size);
 
     FlushMemory(nsString reason);
 
     GarbageCollect();
     CycleCollect();
     
--- a/dom/src/geolocation/nsGeoPosition.cpp
+++ b/dom/src/geolocation/nsGeoPosition.cpp
@@ -36,16 +36,110 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsGeoPosition.h"
 #include "nsDOMClassInfoID.h"
 
 ////////////////////////////////////////////////////
+// nsGeoPositionAddress
+////////////////////////////////////////////////////
+
+nsGeoPositionAddress::nsGeoPositionAddress(const nsAString &aStreetNumber,
+                                           const nsAString &aStreet,
+                                           const nsAString &aPremises,
+                                           const nsAString &aCity,
+                                           const nsAString &aCounty,
+                                           const nsAString &aRegion,
+                                           const nsAString &aCountry,
+                                           const nsAString &aPostalCode)
+    : mStreetNumber(aStreetNumber)
+    , mStreet(aStreet)
+    , mPremises(aPremises)
+    , mCity(aCity)
+    , mCounty(aCounty)
+    , mRegion(aRegion)
+    , mCountry(aCountry)
+    , mPostalCode(aPostalCode)
+{
+}
+
+nsGeoPositionAddress::~nsGeoPositionAddress()
+{
+}
+
+DOMCI_DATA(GeoPositionAddress, nsGeoPositionAddress)
+
+NS_INTERFACE_MAP_BEGIN(nsGeoPositionAddress)
+NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoPositionAddress)
+NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionAddress)
+NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoPositionAddress)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_THREADSAFE_ADDREF(nsGeoPositionAddress)
+NS_IMPL_THREADSAFE_RELEASE(nsGeoPositionAddress)
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetStreetNumber(nsAString & aStreetNumber)
+{
+  aStreetNumber = mStreetNumber;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetStreet(nsAString & aStreet)
+{
+  aStreet = mStreet;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetPremises(nsAString & aPremises)
+{
+  aPremises = mPremises;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetCity(nsAString & aCity)
+{
+  aCity = mCity;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetCounty(nsAString & aCounty)
+{
+  aCounty = mCounty;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetRegion(nsAString & aRegion)
+{
+  aRegion = mRegion;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetCountry(nsAString & aCountry)
+{
+  aCountry = mCountry;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGeoPositionAddress::GetPostalCode(nsAString & aPostalCode)
+{
+  aPostalCode = mPostalCode;
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////
 // nsGeoPositionCoords
 ////////////////////////////////////////////////////
 nsGeoPositionCoords::nsGeoPositionCoords(double aLat, double aLong,
                                          double aAlt, double aHError,
                                          double aVError, double aHeading,
                                          double aSpeed)
   : mLat(aLat)
   , mLong(aLong)
@@ -140,19 +234,21 @@ nsGeoPosition::nsGeoPosition(double aLat
 nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
                              long long aTimestamp) :
     mTimestamp(aTimestamp),
     mCoords(aCoords)
 {
 }
 
 nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
+                             nsIDOMGeoPositionAddress *aAddress,
                              DOMTimeStamp aTimestamp) :
   mTimestamp(aTimestamp),
-  mCoords(aCoords)
+  mCoords(aCoords),
+  mAddress(aAddress)
 {
 }
 
 nsGeoPosition::~nsGeoPosition()
 {
 }
 
 DOMCI_DATA(GeoPosition, nsGeoPosition)
@@ -174,8 +270,16 @@ nsGeoPosition::GetTimestamp(DOMTimeStamp
 }
 
 NS_IMETHODIMP
 nsGeoPosition::GetCoords(nsIDOMGeoPositionCoords * *aCoords)
 {
   NS_IF_ADDREF(*aCoords = mCoords);
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsGeoPosition::GetAddress(nsIDOMGeoPositionAddress** aAddress)
+{
+  NS_IF_ADDREF(*aAddress = mAddress);
+  return NS_OK;
+}
+
--- a/dom/src/geolocation/nsGeoPosition.h
+++ b/dom/src/geolocation/nsGeoPosition.h
@@ -38,21 +38,53 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsGeoPosition_h
 #define nsGeoPosition_h
 
 #include "nsAutoPtr.h"
 #include "nsIClassInfo.h"
 #include "nsDOMClassInfoID.h"
+#include "nsIDOMGeoPositionAddress.h"
 #include "nsIDOMGeoPositionCoords.h"
 #include "nsIDOMGeoPosition.h"
 #include "nsString.h"
 
 ////////////////////////////////////////////////////
+// nsGeoPositionAddress
+////////////////////////////////////////////////////
+
+class nsGeoPositionAddress : public nsIDOMGeoPositionAddress
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOMGEOPOSITIONADDRESS
+
+  nsGeoPositionAddress( const nsAString &aStreetNumber,
+                        const nsAString &aStreet,
+                        const nsAString &aPremises,
+                        const nsAString &aCity,
+                        const nsAString &aCounty,
+                        const nsAString &aRegion,
+                        const nsAString &aCountry,
+                        const nsAString &aPostalCode);
+
+    ~nsGeoPositionAddress();
+  private:
+    const nsString mStreetNumber;
+    const nsString mStreet;
+    const nsString mPremises;
+    const nsString mCity;
+    const nsString mCounty;
+    const nsString mRegion;
+    const nsString mCountry;
+    const nsString mPostalCode;
+};
+
+////////////////////////////////////////////////////
 // nsGeoPositionCoords
 ////////////////////////////////////////////////////
 
 /**
  * Simple object that holds a single point in space.
  */
 class nsGeoPositionCoords MOZ_FINAL : public nsIDOMGeoPositionCoords
 {
@@ -85,18 +117,24 @@ public:
                 double aVError, double aHeading,
                 double aSpeed, long long aTimestamp);
   
 
   nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
                 long long aTimestamp);
 
   nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
+                nsIDOMGeoPositionAddress *aAddress,
                 DOMTimeStamp aTimestamp);
 
+  void SetAddress(nsIDOMGeoPositionAddress *address) {
+    mAddress = address;
+  }
+
 private:
   ~nsGeoPosition();
   long long mTimestamp;
   nsRefPtr<nsIDOMGeoPositionCoords> mCoords;
+  nsRefPtr<nsIDOMGeoPositionAddress> mAddress;
 };
 
 #endif /* nsGeoPosition_h */
 
--- a/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
+++ b/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
@@ -36,22 +36,109 @@
 
 #ifndef dom_src_geolocation_IPC_serialiser
 #define dom_src_geolocation_IPC_serialiser
 
 #include "IPC/IPCMessageUtils.h"
 #include "nsGeoPosition.h"
 #include "nsIDOMGeoPosition.h"
 
+typedef nsIDOMGeoPositionAddress  *GeoPositionAddress;
 typedef nsGeoPositionCoords       *GeoPositionCoords;
 typedef nsIDOMGeoPosition         *GeoPosition;
 
 namespace IPC {
 
 template <>
+struct ParamTraits<GeoPositionAddress>
+{
+  typedef GeoPositionAddress paramType;
+
+  // Function to serialize a geo position address
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    bool isNull = !aParam;
+    WriteParam(aMsg, isNull);
+    // If it is null, then we are done
+    if (isNull) return;
+
+    nsString addressLine;
+
+    aParam->GetStreetNumber(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetStreet(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetPremises(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetCity(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetCounty(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetRegion(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetCountry(addressLine);
+    WriteParam(aMsg, addressLine);
+
+    aParam->GetPostalCode(addressLine);
+    WriteParam(aMsg, addressLine);
+  }
+
+  // Function to de-serialize a geoposition
+  static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
+  {
+    // Check if it is the null pointer we have transfered
+    bool isNull;
+    if (!ReadParam(aMsg, aIter, &isNull)) return false;
+
+    if (isNull) {
+      *aResult = 0;
+      return true;
+    }
+
+    // We need somewhere to store the address before we create the object
+    nsString streetNumber;
+    nsString street;
+    nsString premises;
+    nsString city;
+    nsString county;
+    nsString region;
+    nsString country;
+    nsString postalCode;
+
+    // It's not important to us where it fails, but rather if it fails
+    if (!(ReadParam(aMsg, aIter, &streetNumber) &&
+          ReadParam(aMsg, aIter, &street      ) &&
+          ReadParam(aMsg, aIter, &premises    ) &&
+          ReadParam(aMsg, aIter, &city        ) &&
+          ReadParam(aMsg, aIter, &county      ) &&
+          ReadParam(aMsg, aIter, &region      ) &&
+          ReadParam(aMsg, aIter, &country     ) &&
+          ReadParam(aMsg, aIter, &postalCode  ))) return false;
+
+    // We now have all the data
+    *aResult = new nsGeoPositionAddress(streetNumber, /* aStreetNumber */
+                                        street,       /* aStreet       */
+                                        premises,     /* aPremises     */
+                                        city,         /* aCity         */
+                                        county,       /* aCounty       */
+                                        region,       /* aRegion       */
+                                        country,      /* aCountry      */
+                                        postalCode    /* aPostalCode   */
+                                       );
+    return true;
+  }
+} ;
+
+template <>
 struct ParamTraits<GeoPositionCoords>
 {
   typedef GeoPositionCoords paramType;
 
   // Function to serialize a geoposition
   static void Write(Message *aMsg, const paramType& aParam)
   {
     bool isNull = !aParam;
@@ -143,43 +230,51 @@ struct ParamTraits<GeoPosition>
     DOMTimeStamp timeStamp;
     aParam->GetTimestamp(&timeStamp);
     WriteParam(aMsg, timeStamp);
 
     nsCOMPtr<nsIDOMGeoPositionCoords> coords;
     aParam->GetCoords(getter_AddRefs(coords));
     GeoPositionCoords simpleCoords = static_cast<GeoPositionCoords>(coords.get());
     WriteParam(aMsg, simpleCoords);
+
+    nsCOMPtr<nsIDOMGeoPositionAddress> address;
+    aParam->GetAddress(getter_AddRefs(address));
+    GeoPositionAddress simpleAddress = address.get();
+    WriteParam(aMsg, simpleAddress);
   }
 
   // Function to de-serialize a geoposition
   static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
   {
     // Check if it is the null pointer we have transfered
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) return false;
 
     if (isNull) {
       *aResult = 0;
       return true;
     }
 
     DOMTimeStamp timeStamp;
     GeoPositionCoords coords = nsnull;
+    GeoPositionAddress address;
 
     // It's not important to us where it fails, but rather if it fails
     if (!(   ReadParam(aMsg, aIter, &timeStamp)
-          && ReadParam(aMsg, aIter, &coords   ))) {
+          && ReadParam(aMsg, aIter, &coords   )
+          && ReadParam(aMsg, aIter, &address  ))) {
           // note it is fine to do "delete nsnull" in case coords hasn't
-          // been allocated
+          // been allocated and we will never have a case where address
+          // gets allocated and we end here
           delete coords;
           return false;
       }
 
-    *aResult = new nsGeoPosition(coords, timeStamp);
+    *aResult = new nsGeoPosition(coords, address, timeStamp);
 
     return true;
   };
 
 };
 
 }
 
--- a/dom/system/Makefile.in
+++ b/dom/system/Makefile.in
@@ -82,19 +82,16 @@ EXTRA_COMPONENTS = \
   GPSDGeolocationProvider.manifest \
   $(NULL)
 endif
 
 EXPORTS     = \
   nsDeviceMotion.h \
   $(NULL)
 
-# We fire the nsDOMDeviceAcceleration
-LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
-
 include $(topsrcdir)/config/config.mk
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/android/Makefile.in
+++ b/dom/system/android/Makefile.in
@@ -54,13 +54,12 @@ include $(topsrcdir)/ipc/chromium/chromi
 
 CPPSRCS     = \
         nsDeviceMotionSystem.cpp \
         AndroidLocationProvider.cpp \
         nsHapticFeedback.cpp \
         $(NULL)
 
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/src/geolocation \
-                     -I$(topsrcdir)/content/events/src
                      $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/system/cocoa/Makefile.in
+++ b/dom/system/cocoa/Makefile.in
@@ -44,19 +44,15 @@ include $(DEPTH)/config/autoconf.mk
 MODULE      = dom
 LIBRARY_NAME    = domsystemcocoa_s
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
-# We fire the nsDOMDeviceAcceleration
-LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
-
 include $(topsrcdir)/config/config.mk
 
 CMMSRCS     = \
-        smslib.mm \
         nsDeviceMotionSystem.mm \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/cocoa/nsDeviceMotionSystem.mm
+++ b/dom/system/cocoa/nsDeviceMotionSystem.mm
@@ -37,60 +37,171 @@
 #include "nsDeviceMotionSystem.h"
 #include "nsIServiceManager.h"
 #include "stdlib.h"
 
 #include <sys/sysctl.h>
 #include <sys/resource.h>
 #include <sys/vm.h>
 
-#import "smslib.h"
-#define MEAN_GRAVITY 9.80665
-#define DEFAULT_SENSOR_POLL 100
+#define MODEL_NAME_LENGTH 64
+static char gModelName[MODEL_NAME_LENGTH];
 
 nsDeviceMotionSystem::nsDeviceMotionSystem()
 {
 }
 
 nsDeviceMotionSystem::~nsDeviceMotionSystem()
 {
 }
 
+// Data format returned from IOConnectMethodStructureIStructureO.
+// I am not sure what the other bits in this structure are,
+// or if there are any, but this has to be 40 bytes long or
+// the call to read fails.
+//
+// Since we make the SmsData struct larger than any members we plan to access we
+// keep track of the the size of the part of the struct we plan to access for
+// use in bounds checking.
+#define SMSDATA_PADDING_SIZE 34
+typedef struct
+{
+  PRInt16 x;
+  PRInt16 y;
+  PRInt16 z;
+  PRInt8  unknown[SMSDATA_PADDING_SIZE];
+} SmsData;
+#define SMSDATA_USED_SIZE (sizeof(SmsData) - SMSDATA_PADDING_SIZE)
+
 void
 nsDeviceMotionSystem::UpdateHandler(nsITimer *aTimer, void *aClosure)
 {
   nsDeviceMotionSystem *self = reinterpret_cast<nsDeviceMotionSystem *>(aClosure);
   if (!self) {
     NS_ERROR("no self");
     return;
   }
-  sms_acceleration accel;
-  smsGetData(&accel);
+
+  size_t bufferLen = sizeof(SmsData);
+
+  void * input = malloc(bufferLen);
+  void * output = malloc(bufferLen);
+
+  if (!input || !output)
+    return;
+
+  memset(input, 0, bufferLen);
+  memset(output, 0, bufferLen);
+
+  size_t structureOutputSize = bufferLen;
+#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
+  kern_return_t result = ::IOConnectMethodStructureIStructureO(self->mSmsConnection,
+                                                               5, /* Magic number for SMCMotionSensor */
+                                                               bufferLen,
+                                                               (IOByteCount*)&structureOutputSize,
+                                                               input,
+                                                               output);
+#else
+  kern_return_t result = ::IOConnectCallStructMethod((mach_port_t)self->mSmsConnection,
+                                                     5, /* Magic number for SMCMotionSensor */
+                                                     input,
+                                                     bufferLen,
+                                                     output,
+                                                     &structureOutputSize);
+#endif
 
-  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
-			    accel.x * MEAN_GRAVITY,
-			    accel.y * MEAN_GRAVITY,
-			    accel.z * MEAN_GRAVITY);
+  if ((result != kIOReturnSuccess) || (structureOutputSize < SMSDATA_USED_SIZE)) {
+    free(input);
+    free(output);
+    return;
+  }
+
+  SmsData *data = (SmsData*) output;
+
+  float xf, yf, zf;
+
+  // we want to normalize the return result from the chip to
+  // something between -1 and 1 where 0 is the balance point.
+
+  const int normalizeFactor = 250.5;
+
+  if (!strcmp(gModelName, "MacBookPro5,1")) {
+    xf = ((float)data->x) / normalizeFactor;
+    yf = (((float)data->y) / normalizeFactor) * -1;
+    zf = ((float)data->z) / normalizeFactor;
+  }
+  else if (!strcmp(gModelName, "MacBookPro5,3")) {
+    xf = ((float)data->y) / normalizeFactor;
+    yf = (((float)data->x) / normalizeFactor) * -1;
+    zf = (((float)data->z) / normalizeFactor) * -1;
+  }
+  else
+  {
+    xf = (((float)data->x) / normalizeFactor) * -1;
+    yf = ((float)data->y) / normalizeFactor;
+    zf = ((float)data->z) / normalizeFactor;
+  }
+
+  free(input);
+  free(output);
+
+  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, xf, yf, zf );
 }
 
 void nsDeviceMotionSystem::Startup()
 {
-  smsStartup(nil, nil);
-  smsLoadCalibration();
+  // we can fail, and that just means the caller will not see any changes.
+
+  mach_port_t port;
+  kern_return_t result = ::IOMasterPort(MACH_PORT_NULL, &port);
+  if (result != kIOReturnSuccess)
+    return;
+
+  CFMutableDictionaryRef  dict = ::IOServiceMatching("SMCMotionSensor");
+  if (!dict)
+    return;
+
+  io_iterator_t iter;
+  result = ::IOServiceGetMatchingServices(port, dict, &iter);
+  if (result != kIOReturnSuccess)
+    return;
+
+  io_object_t device = ::IOIteratorNext(iter);
+
+  ::IOObjectRelease(iter);
+
+  if (!device)
+    return;
+
+  result = ::IOServiceOpen(device, mach_task_self(), 0, &mSmsConnection);
+  ::IOObjectRelease(device);
+
+  if (result != kIOReturnSuccess)
+    return;
+
+  mach_port_deallocate(mach_task_self(), port);
+
+  /* get the version of the hardware we are running on. */
+  int mib[2];
+  size_t len = MODEL_NAME_LENGTH;
+  mib[0] = CTL_HW;
+  mib[1] = HW_MODEL;
+  sysctl(mib, 2, gModelName, &len, NULL, 0);
 
   mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
   if (mUpdateTimer)
     mUpdateTimer->InitWithFuncCallback(UpdateHandler,
                                        this,
-                                       DEFAULT_SENSOR_POLL,
+                                       mUpdateInterval,
                                        nsITimer::TYPE_REPEATING_SLACK);
 }
 
 void nsDeviceMotionSystem::Shutdown()
 {
+  if (mSmsConnection)
+    ::IOServiceClose(mSmsConnection);
+
   if (mUpdateTimer) {
     mUpdateTimer->Cancel();
     mUpdateTimer = nsnull;
   }
-
-  smsShutdown();
 }
 
deleted file mode 100644
--- a/dom/system/cocoa/smslib.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * smslib.h
- *
- * SMSLib Sudden Motion Sensor Access Library
- * Copyright (c) 2010 Suitable Systems
- * All rights reserved.
- * 
- * Developed by: Daniel Griscom
- *               Suitable Systems
- *               http://www.suitable.com
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal with the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimers.
- * 
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimers in the
- * documentation and/or other materials provided with the distribution.
- * 
- * - Neither the names of Suitable Systems nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this Software without specific prior written permission.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
- *
- * For more information about SMSLib, see
- *		<http://www.suitable.com/tools/smslib.html>
- * or contact
- *		Daniel Griscom
- *		Suitable Systems
- *		1 Centre Street, Suite 204
- *		Wakefield, MA 01880
- *		(781) 665-0053
- *
- */
-
-#import <Foundation/Foundation.h>
-
-#define SMSLIB_VERSION "1.8"
-
-#pragma mark Structure definitions
-
-// Structure for specifying a 3-axis acceleration. 0.0 means "zero gravities",
-// 1.0 means "one gravity".
-typedef struct sms_acceleration {
-	float x;		// Right-left acceleration (positive is rightwards)
-	float y;		// Front-rear acceleration (positive is rearwards)
-	float z;		// Up-down acceleration (positive is upwards)
-} sms_acceleration;
-
-// Structure for specifying a calibration.
-typedef struct sms_calibration {
-	float zeros[3];	// Zero points for three axes (X, Y, Z)
-	float onegs[3];	// One gravity values for three axes
-} sms_calibration;
-
-#pragma mark Return value definitions
-
-// These are the return values for accelStartup(), giving the
-// various stages where the most successful attempt at accessing
-// the accelerometer failed. The higher the value, the further along the
-// software progressed before failing. The options are:
-//	- Didn't match model name
-#define SMS_FAIL_MODEL			(-7)
-//	- Failure getting dictionary matching desired services
-#define SMS_FAIL_DICTIONARY		(-6)
-//	- Failure getting list of services
-#define SMS_FAIL_LIST_SERVICES	(-5)
-//	- Failure if list of services is empty. The process generally fails
-//		here if run on a machine without a Sudden Motion Sensor.
-#define SMS_FAIL_NO_SERVICES	(-4)
-//	- Failure if error opening device.
-#define SMS_FAIL_OPENING		(-3)
-//	- Failure if opened, but didn't get a connection
-#define SMS_FAIL_CONNECTION		(-2)
-//	- Failure if couldn't access connction using given function and size. This
-//		is where the process would probably fail with a change in Apple's API.
-//		Driver problems often also cause failures here.
-#define SMS_FAIL_ACCESS			(-1)
-//	- Success!
-#define SMS_SUCCESS				(0)
-
-#pragma mark Function declarations
-
-// This starts up the accelerometer code, trying each possible sensor
-// specification. Note that for logging purposes it
-// takes an object and a selector; the object's selector is then invoked
-// with a single NSString as argument giving progress messages. Example
-// logging method:
-//		- (void)logMessage: (NSString *)theString
-// which would be used in accelStartup's invocation thusly:
-//		result = accelStartup(self, @selector(logMessage:));
-// If the object is nil, then no logging is done. Sets calibation from built-in
-// value table. Returns ACCEL_SUCCESS for success, and other (negative)
-// values for various failures (returns value indicating result of
-// most successful trial).
-int smsStartup(id logObject, SEL logSelector);
-
-// This starts up the library in debug mode, ignoring the actual hardware.
-// Returned data is in the form of 1Hz sine waves, with the X, Y and Z
-// axes 120 degrees out of phase; "calibrated" data has range +/- (1.0/5);
-// "uncalibrated" data has range +/- (256/5). X and Y axes centered on 0.0,
-// Z axes centered on 1 (calibrated) or 256 (uncalibrated). 
-// Don't use smsGetBufferLength or smsGetBufferData. Always returns SMS_SUCCESS.
-int smsDebugStartup(id logObject, SEL logSelector);
-
-// Returns the current calibration values.
-void smsGetCalibration(sms_calibration *calibrationRecord);
-
-// Sets the calibration, but does NOT store it as a preference. If the argument
-// is nil then the current calibration is set from the built-in value table.
-void smsSetCalibration(sms_calibration *calibrationRecord);
-
-// Stores the current calibration values as a stored preference.
-void smsStoreCalibration(void);
-
-// Loads the stored preference values into the current calibration.
-// Returns YES if successful.
-BOOL smsLoadCalibration(void);
-
-// Deletes any stored calibration, and then takes the current calibration values
-// from the built-in value table.
-void smsDeleteCalibration(void);
-
-// Fills in the accel record with calibrated acceleration data. Takes
-// 1-2ms to return a value. Returns 0 if success, error number if failure.
-int smsGetData(sms_acceleration *accel);
-
-// Fills in the accel record with uncalibrated acceleration data.
-// Returns 0 if success, error number if failure.
-int smsGetUncalibratedData(sms_acceleration *accel);
-
-// Returns the length of a raw block of data for the current type of sensor.
-int smsGetBufferLength(void);
-
-// Takes a pointer to accelGetRawLength() bytes; sets those bytes
-// to return value from sensor. Make darn sure the buffer length is right!
-void smsGetBufferData(char *buffer);
-
-// This returns an NSString describing the current calibration in
-// human-readable form. Also include a description of the machine.
-NSString *smsGetCalibrationDescription(void);
-
-// Shuts down the accelerometer.
-void smsShutdown(void);
-
deleted file mode 100644
--- a/dom/system/cocoa/smslib.mm
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * smslib.m
- * 
- * SMSLib Sudden Motion Sensor Access Library
- * Copyright (c) 2010 Suitable Systems
- * All rights reserved.
- * 
- * Developed by: Daniel Griscom
- *               Suitable Systems
- *               http://www.suitable.com
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal with the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimers.
- * 
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimers in the
- * documentation and/or other materials provided with the distribution.
- * 
- * - Neither the names of Suitable Systems nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this Software without specific prior written permission.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
- *
- * For more information about SMSLib, see
- *		<http://www.suitable.com/tools/smslib.html>
- * or contact
- *		Daniel Griscom
- *		Suitable Systems
- *		1 Centre Street, Suite 204
- *		Wakefield, MA 01880
- *		(781) 665-0053
- *
- */
-
-#import <IOKit/IOKitLib.h>
-#import <sys/sysctl.h>
-#import <math.h>
-#import "smslib.h"
-
-#pragma mark Internal structures
-
-// Represents a single axis of a type of sensor.
-typedef struct axisStruct {
-	int enabled;				// Non-zero if axis is valid in this sensor
-	int index;					// Location in struct of first byte
-	int size;					// Number of bytes
-	float zerog;				// Value meaning "zero g"
-	float oneg;					// Change in value meaning "increase of one g"
-								// (can be negative if axis sensor reversed)
-} axisStruct;
-
-// Represents the configuration of a type of sensor.
-typedef struct sensorSpec {
-	char *model;				// Prefix of model to be tested
-	char *name;					// Name of device to be read
-	unsigned int function;		// Kernel function index
-	int recordSize;				// Size of record to be sent/received
-	axisStruct axes[3];			// Description of three axes (X, Y, Z)
-} sensorSpec;
-	
-// Configuration of all known types of sensors. The configurations are
-// tried in order until one succeeds in returning data.
-// All default values are set here, but each axis' zerog and oneg values 
-// may be changed to saved (calibrated) values.
-//
-// These values came from SeisMaCalibrate calibration reports. In general I've
-// found the following:
-//	- All Intel-based SMSs have 250 counts per g, centered on 0, but the signs
-//		are different (and in one case two axes are swapped)
-//	- PowerBooks and iBooks all have sensors centered on 0, and reading
-//		50-53 steps per gravity (but with differing polarities!)
-//	- PowerBooks and iBooks of the same model all have the same axis polarities
-//	- PowerBook and iBook access methods are model- and OS version-specific
-//
-// So, the sequence of tests is:
-//	- Try model-specific access methods. Note that the test is for a match to the
-//		beginning of the model name, e.g. the record with model name "MacBook"
-//		matches computer models "MacBookPro1,2" and "MacBook1,1" (and ""
-//		matches any model).
-//	- If no model-specific record's access fails, then try each model-independent
-//		access method in order, stopping when one works.
-static const sensorSpec sensors[] = {
-	// ****** Model-dependent methods ******
-	// The PowerBook5,6 is one of the G4 models that seems to lose
-	// SMS access until the next reboot.
-	{"PowerBook5,6", "IOI2CMotionSensor", 21, 60, {
-			{1, 0, 1, 0,  51.5},
-			{1, 1, 1, 0, -51.5},
-			{1, 2, 1, 0, -51.5}
-		}
-	},
-	// The PowerBook5,7 is one of the G4 models that seems to lose
-	// SMS access until the next reboot.
-	{"PowerBook5,7", "IOI2CMotionSensor", 21, 60, {
-			{1, 0, 1, 0,  51.5},
-			{1, 1, 1, 0,  51.5},
-			{1, 2, 1, 0,  51.5}
-		}
-	},
-	// Access seems to be reliable on the PowerBook5,8
-	{"PowerBook5,8", "PMUMotionSensor", 21, 60, {
-			{1, 0, 1, 0, -51.5},
-			{1, 1, 1, 0,  51.5},
-			{1, 2, 1, 0, -51.5}
-		}
-	},
-	// Access seems to be reliable on the PowerBook5,9
-	{"PowerBook5,9", "PMUMotionSensor", 21, 60, {
-			{1, 0, 1, 0,  51.5},
-			{1, 1, 1, 0, -51.5},
-			{1, 2, 1, 0, -51.5}
-		}
-	},
-	// The PowerBook6,7 is one of the G4 models that seems to lose
-	// SMS access until the next reboot.
-	{"PowerBook6,7", "IOI2CMotionSensor", 21, 60, {
-			{1, 0, 1, 0,  51.5},
-			{1, 1, 1, 0,  51.5},
-			{1, 2, 1, 0,  51.5}
-		}
-	},
-	// The PowerBook6,8 is one of the G4 models that seems to lose
-	// SMS access until the next reboot.
-	{"PowerBook6,8", "IOI2CMotionSensor", 21, 60, {
-			{1, 0, 1, 0,  51.5},
-			{1, 1, 1, 0,  51.5},
-			{1, 2, 1, 0,  51.5}
-		}
-	},
-	// MacBook Pro Core 2 Duo 17". Note the reversed Y and Z axes.
-	{"MacBookPro2,1", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0,  251},
-			{1, 2, 2, 0, -251},
-			{1, 4, 2, 0, -251}
-		}
-	},
-	// MacBook Pro Core 2 Duo 15" AND 17" with LED backlight, introduced June '07.
-	// NOTE! The 17" machines have the signs of their X and Y axes reversed
-	// from this calibration, but there's no clear way to discriminate between
-	// the two machines.
-	{"MacBookPro3,1", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0, -251},
-			{1, 2, 2, 0,  251},
-			{1, 4, 2, 0, -251}
-		}
-	},
-	// ... specs?
-	{"MacBook5,2", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0, -251},
-			{1, 2, 2, 0,  251},
-			{1, 4, 2, 0, -251}
-		}
-	},
-	// ... specs?
-	{"MacBookPro5,1", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0, -251},
-			{1, 2, 2, 0, -251},
-			{1, 4, 2, 0,  251}
-		}
-	},
-	// ... specs?
-	{"MacBookPro5,2", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0, -251},
-			{1, 2, 2, 0, -251},
-			{1, 4, 2, 0,  251}
-		}
-	},
-	// This is speculative, based on a single user's report. Looks like the X and Y axes
-	// are swapped. This is true for no other known Appple laptop.
-	{"MacBookPro5,3", "SMCMotionSensor", 5, 40, {
-			{1, 2, 2, 0, -251},
-			{1, 0, 2, 0, -251},
-			{1, 4, 2, 0, -251}
-		}
-	},
-	// ... specs?
-	{"MacBookPro5,4", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0, -251},
-			{1, 2, 2, 0, -251},
-			{1, 4, 2, 0,  251}
-		}
-	},
-	// ****** Model-independent methods ******
-	// Seen once with PowerBook6,8 under system 10.3.9; I suspect
-	// other G4-based 10.3.* systems might use this
-	{"", "IOI2CMotionSensor", 24, 60, {
-			{1, 0, 1, 0, 51.5},
-			{1, 1, 1, 0, 51.5},
-			{1, 2, 1, 0, 51.5}
-		}
-	},
-	// PowerBook5,6 , PowerBook5,7 , PowerBook6,7 , PowerBook6,8
-	// under OS X 10.4.*
-	{"", "IOI2CMotionSensor", 21, 60, {
-			{1, 0, 1, 0, 51.5},
-			{1, 1, 1, 0, 51.5},
-			{1, 2, 1, 0, 51.5}
-		}
-	},
-	// PowerBook5,8 , PowerBook5,9 under OS X 10.4.*
-	{"", "PMUMotionSensor", 21, 60, {
-			// Each has two out of three gains negative, but it's different
-			// for the different models. So, this will be right in two out
-			// of three axis for either model.
-			{1, 0, 1,  0, -51.5},
-			{1, 1, 1, -6, -51.5},
-			{1, 2, 1,  0, -51.5}
-		}
-	},
-	// All MacBook, MacBookPro models. Hardware (at least on early MacBookPro 15")
-	// is Kionix KXM52-1050 three-axis accelerometer chip. Data is at
-	// http://kionix.com/Product-Index/product-index.htm. Specific MB and MBP models
-	// that use this are: 
-	//		MacBook1,1
-	//		MacBook2,1
-	//		MacBook3,1
-	//		MacBook4,1
-	//		MacBook5,1
-	//		MacBook6,1
-	//		MacBookAir1,1
-	//		MacBookPro1,1
-	//		MacBookPro1,2
-	//		MacBookPro4,1
-	//		MacBookPro5,5
-	{"", "SMCMotionSensor", 5, 40, {
-			{1, 0, 2, 0, 251},
-			{1, 2, 2, 0, 251},
-			{1, 4, 2, 0, 251}
-		}
-	}
-};
-
-#define SENSOR_COUNT (sizeof(sensors)/sizeof(sensorSpec))
-
-#pragma mark Internal prototypes
-
-static int getData(sms_acceleration *accel, int calibrated, id logObject, SEL logSelector);
-static float getAxis(int which, int calibrated);
-static int signExtend(int value, int size);
-static NSString *getModelName(void);
-static NSString *getOSVersion(void);
-static BOOL loadCalibration(void);
-static void storeCalibration(void);
-static void defaultCalibration(void);
-static void deleteCalibration(void);
-static int prefIntRead(NSString *prefName, BOOL *success);
-static void prefIntWrite(NSString *prefName, int prefValue);
-static float prefFloatRead(NSString *prefName, BOOL *success);
-static void prefFloatWrite(NSString *prefName, float prefValue);
-static void prefDelete(NSString *prefName);
-static void prefSynchronize(void);
-// static long getMicroseconds(void);
-float fakeData(NSTimeInterval time);
-
-#pragma mark Static variables
-
-static int debugging = NO;		// True if debugging (synthetic data)
-static io_connect_t connection;	// Connection for reading accel values
-static int running = NO;		// True if we successfully started
-static int sensorNum = 0;		// The current index into sensors[]
-static char *serviceName;		// The name of the current service
-static char *iRecord, *oRecord;	// Pointers to read/write records for sensor
-static int recordSize;			// Size of read/write records
-static unsigned int function;	// Which kernel function should be used
-static float zeros[3];			// X, Y and Z zero calibration values
-static float onegs[3];			// X, Y and Z one-g calibration values
-
-#pragma mark Defines
-
-// Pattern for building axis letter from axis number
-#define INT_TO_AXIS(a) (a == 0 ? @"X" : a == 1 ? @"Y" : @"Z")
-// Name of configuration for given axis' zero (axis specified by integer)
-#define ZERO_NAME(a) [NSString stringWithFormat:@"%@-Axis-Zero", INT_TO_AXIS(a)]
-// Name of configuration for given axis' oneg (axis specified by integer)
-#define ONEG_NAME(a) [NSString stringWithFormat:@"%@-Axis-One-g", INT_TO_AXIS(a)]
-// Name of "Is calibrated" preference
-#define CALIBRATED_NAME (@"Calibrated")
-// Application domain for SeisMac library
-#define APP_ID ((CFStringRef)@"com.suitable.SeisMacLib")
-
-// These #defines make the accelStartup code a LOT easier to read.
-#define LOG(message) \
-	if (logObject) { \
-		[logObject performSelector:logSelector withObject:message]; \
-	}
-#define LOG_ARG(format, var1) \
-	if (logObject) { \
-		[logObject performSelector:logSelector \
-			withObject:[NSString stringWithFormat:format, var1]]; \
-	}
-#define LOG_2ARG(format, var1, var2) \
-	if (logObject) { \
-		[logObject performSelector:logSelector \
-			withObject:[NSString stringWithFormat:format, var1, var2]]; \
-	}
-#define LOG_3ARG(format, var1, var2, var3) \
-	if (logObject) { \
-		[logObject performSelector:logSelector \
-			withObject:[NSString stringWithFormat:format, var1, var2, var3]]; \
-	}
-
-#pragma mark Function definitions
-
-// This starts up the accelerometer code, trying each possible sensor
-// specification. Note that for logging purposes it
-// takes an object and a selector; the object's selector is then invoked
-// with a single NSString as argument giving progress messages. Example
-// logging method:
-//		- (void)logMessage: (NSString *)theString
-// which would be used in accelStartup's invocation thusly:
-//		result = accelStartup(self, @selector(logMessage:));
-// If the object is nil, then no logging is done. Sets calibation from built-in
-// value table. Returns ACCEL_SUCCESS for success, and other (negative)
-// values for various failures (returns value indicating result of
-// most successful trial).
-int smsStartup(id logObject, SEL logSelector) {
-	io_iterator_t iterator;
-	io_object_t device;
-	kern_return_t result;
-	sms_acceleration accel;
-	int failure_result = SMS_FAIL_MODEL;
-		
-	running = NO;
-	debugging = NO;
-	
-	NSString *modelName = getModelName();
-	
-	LOG_ARG(@"Machine model: %@\n", modelName);
-	LOG_ARG(@"OS X version: %@\n", getOSVersion());
-	LOG_ARG(@"Accelerometer library version: %s\n", SMSLIB_VERSION);
-		
-	for (sensorNum = 0; sensorNum < SENSOR_COUNT; sensorNum++) {
-		
-		// Set up all specs for this type of sensor
-		serviceName = sensors[sensorNum].name;
-		recordSize = sensors[sensorNum].recordSize;
-		function = sensors[sensorNum].function;
-		
-		LOG_3ARG(@"Trying service \"%s\" with selector %d and %d byte record:\n",
-				serviceName, function, recordSize);
-		
-		NSString *targetName = [NSString stringWithCString:sensors[sensorNum].model
-												  encoding:NSMacOSRomanStringEncoding];
-		LOG_ARG(@"    Comparing model name to target \"%@\": ", targetName);
-		if ([targetName length] == 0 || [modelName hasPrefix:targetName]) {
-			LOG(@"success.\n");
-		} else {
-			LOG(@"failure.\n");
-			// Don't need to increment failure_result.
-			continue;
-		}
-		
-		LOG(@"    Fetching dictionary for service: ");
-		CFMutableDictionaryRef dict = IOServiceMatching(serviceName);
-		
-		if (dict) {
-			LOG(@"success.\n");
-		} else {
-			LOG(@"failure.\n");
-			if (failure_result < SMS_FAIL_DICTIONARY) {
-				failure_result = SMS_FAIL_DICTIONARY;
-			}
-			continue;
-		}
-		
-		LOG(@"    Getting list of matching services: ");
-		result = IOServiceGetMatchingServices(kIOMasterPortDefault, 
-										 dict, 
-										 &iterator);
-		
-		if (result == KERN_SUCCESS) {
-			LOG(@"success.\n");
-		} else {
-			LOG_ARG(@"failure, with return value 0x%x.\n", result);
-			if (failure_result < SMS_FAIL_LIST_SERVICES) {
-				failure_result = SMS_FAIL_LIST_SERVICES;
-			}
-			continue;
-		}
-		
-		LOG(@"    Getting first device in list: ");
-		device = IOIteratorNext(iterator);	
-		
-		if (device == 0) {
-			LOG(@"failure.\n");
-			if (failure_result < SMS_FAIL_NO_SERVICES) {
-				failure_result = SMS_FAIL_NO_SERVICES;
-			}
-			continue;
-		} else {
-			LOG(@"success.\n");
-			LOG(@"    Opening device: ");
-		}
-		
-		result = IOServiceOpen(device, mach_task_self(), 0, &connection);
-		
-		if (result != KERN_SUCCESS) {
-			LOG_ARG(@"failure, with return value 0x%x.\n", result);
-			IOObjectRelease(device);
-			if (failure_result < SMS_FAIL_OPENING) {
-				failure_result = SMS_FAIL_OPENING;
-			}
-			continue;
-		} else if (connection == 0) {
-			LOG_ARG(@"'success', but didn't get a connection.\n", result);
-			IOObjectRelease(device);
-			if (failure_result < SMS_FAIL_CONNECTION) {
-				failure_result = SMS_FAIL_CONNECTION;
-			}
-			continue;
-		} else {
-			IOObjectRelease(device);
-			LOG(@"success.\n");
-		}
-		LOG(@"    Testing device.\n");
-		
-		defaultCalibration();
-		
-		iRecord = (char*) malloc(recordSize);
-		oRecord = (char*) malloc(recordSize);
-		
-		running = YES;
-		result = getData(&accel, true, logObject, logSelector);
-		running = NO;
-		
-		if (result) {
-			LOG_ARG(@"    Failure testing device, with result 0x%x.\n", result);
-			free(iRecord);
-			iRecord = 0;
-			free(oRecord);
-			oRecord = 0;
-			if (failure_result < SMS_FAIL_ACCESS) {
-				failure_result = SMS_FAIL_ACCESS;
-			}
-			continue;
-		} else {
-			LOG(@"    Success testing device!\n");
-			running = YES;
-			return SMS_SUCCESS;
-		}
-	}
-	return failure_result;
-}
-
-// This starts up the library in debug mode, ignoring the actual hardware.
-// Returned data is in the form of 1Hz sine waves, with the X, Y and Z
-// axes 120 degrees out of phase; "calibrated" data has range +/- (1.0/5);
-// "uncalibrated" data has range +/- (256/5). X and Y axes centered on 0.0,
-// Z axes centered on 1 (calibrated) or 256 (uncalibrated). 
-// Don't use smsGetBufferLength or smsGetBufferData. Always returns SMS_SUCCESS.
-int smsDebugStartup(id logObject, SEL logSelector) {
-	LOG(@"Starting up in debug mode\n");
-	debugging = YES;
-	return SMS_SUCCESS;
-}
-
-// Returns the current calibration values.
-void smsGetCalibration(sms_calibration *calibrationRecord) {
-	int x;
-	
-	for (x = 0; x < 3; x++) {
-		calibrationRecord->zeros[x] = (debugging ? 0 : zeros[x]);
-		calibrationRecord->onegs[x] = (debugging ? 256 : onegs[x]);
-	}
-}
-
-// Sets the calibration, but does NOT store it as a preference. If the argument
-// is nil then the current calibration is set from the built-in value table.
-void smsSetCalibration(sms_calibration *calibrationRecord) {
-	int x;
-	
-	if (!debugging) {
-		if (calibrationRecord) {
-			for (x = 0; x < 3; x++) {
-				zeros[x] = calibrationRecord->zeros[x];
-				onegs[x] = calibrationRecord->onegs[x];
-			}
-		} else {
-			defaultCalibration();
-		}
-	}
-}
-
-// Stores the current calibration values as a stored preference.
-void smsStoreCalibration(void) {
-	if (!debugging)
-		storeCalibration();
-}
-
-// Loads the stored preference values into the current calibration.
-// Returns YES if successful.
-BOOL smsLoadCalibration(void) {
-	if (debugging) {
-		return YES;
-	} else if (loadCalibration()) {
-		return YES;
-	} else {
-		defaultCalibration();
-		return NO;
-	}
-}
-
-// Deletes any stored calibration, and then takes the current calibration values
-// from the built-in value table.
-void smsDeleteCalibration(void) {
-	if (!debugging) {
-		deleteCalibration();
-		defaultCalibration();
-	}
-}
-
-// Fills in the accel record with calibrated acceleration data. Takes
-// 1-2ms to return a value. Returns 0 if success, error number if failure.
-int smsGetData(sms_acceleration *accel) {
-	NSTimeInterval time;
-	if (debugging) {
-		usleep(1500);						// Usually takes 1-2 milliseconds
-		time = [NSDate timeIntervalSinceReferenceDate];
-		accel->x = fakeData(time)/5;
-		accel->y = fakeData(time - 1)/5;
-		accel->z = fakeData(time - 2)/5 + 1.0;
-		return true;
-	} else {
-		return getData(accel, true, nil, nil);
-	}
-}
-
-// Fills in the accel record with uncalibrated acceleration data.
-// Returns 0 if success, error number if failure.
-int smsGetUncalibratedData(sms_acceleration *accel) {
-	NSTimeInterval time;
-	if (debugging) {
-		usleep(1500);						// Usually takes 1-2 milliseconds
-		time = [NSDate timeIntervalSinceReferenceDate];
-		accel->x = fakeData(time) * 256 / 5;
-		accel->y = fakeData(time - 1) * 256 / 5;
-		accel->z = fakeData(time - 2) * 256 / 5 + 256;
-		return true;
-	} else {
-		return getData(accel, false, nil, nil);
-	}
-}
-
-// Returns the length of a raw block of data for the current type of sensor.
-int smsGetBufferLength(void) {
-	if (debugging) {
-		return 0;
-	} else if (running) {
-		return sensors[sensorNum].recordSize;
-	} else {
-		return 0;
-	}
-}
-
-// Takes a pointer to accelGetRawLength() bytes; sets those bytes
-// to return value from sensor. Make darn sure the buffer length is right!
-void smsGetBufferData(char *buffer) {
-	IOItemCount iSize = recordSize;
-	IOByteCount oSize = recordSize;
-	kern_return_t result;
-
-	if (debugging || running == NO) {
-		return;
-	}
-
-	memset(iRecord, 1, iSize);
-	memset(buffer, 0, oSize);
-#if __MAC_OS_X_VERSION_MIN_REQUIRED  >= 1050
-	const size_t InStructSize = recordSize;
-	size_t OutStructSize = recordSize;
-	result = IOConnectCallStructMethod(connection,
-						function,				// magic kernel function number
-						(const void *)iRecord,
-						InStructSize,
-						(void *)buffer,
-						&OutStructSize
-					);
-#else // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
-	result = IOConnectMethodStructureIStructureO(connection,
-						function,				// magic kernel function number
-						iSize,
-						&oSize,
-						iRecord,
-						buffer
-					);
-#endif // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
-	
-	if (result != KERN_SUCCESS) {
-		running = NO;
-	}
-}
-
-// This returns an NSString describing the current calibration in
-// human-readable form. Also include a description of the machine.
-NSString *smsGetCalibrationDescription(void) {
-	BOOL success;
-	NSMutableString *s = [[NSMutableString alloc] init];
-	
-	if (debugging) {
-		[s release];
-		return @"Debugging!";
-	}
-	
-	[s appendString:@"---- SeisMac Calibration Record ----\n \n"];
-	[s appendFormat:@"Machine model: %@\n", 
-		getModelName()];
-	[s appendFormat:@"OS X build: %@\n", 
-		getOSVersion()];
-	[s appendFormat:@"SeisMacLib version %s, record %d\n \n", 
-		SMSLIB_VERSION, sensorNum];
-	[s appendFormat:@"Using service \"%s\", function index %d, size %d\n \n",
-		serviceName, function, recordSize];
-	if (prefIntRead(CALIBRATED_NAME, &success) && success) {
-		[s appendString:@"Calibration values (from calibration):\n"];
-	} else {
-		[s appendString:@"Calibration values (from defaults):\n"];
-	}
-	[s appendFormat:@"    X-Axis-Zero  = %.2f\n", zeros[0]];
-	[s appendFormat:@"    X-Axis-One-g = %.2f\n", onegs[0]];
-	[s appendFormat:@"    Y-Axis-Zero  = %.2f\n", zeros[1]];
-	[s appendFormat:@"    Y-Axis-One-g = %.2f\n", onegs[1]];
-	[s appendFormat:@"    Z-Axis-Zero  = %.2f\n", zeros[2]];
-	[s appendFormat:@"    Z-Axis-One-g = %.2f\n \n", onegs[2]];
-	[s appendString:@"---- End Record ----\n"];
-	return s;
-}
-
-// Shuts down the accelerometer.
-void smsShutdown(void) {
-	if (!debugging) {
-		running = NO;
-		if (iRecord) free(iRecord);
-		if (oRecord) free(oRecord);
-		IOServiceClose(connection);
-	}
-}
-
-#pragma mark Internal functions
-
-// Loads the current calibration from the stored preferences.
-// Returns true iff successful.
-BOOL loadCalibration(void) {
-	BOOL thisSuccess, allSuccess;
-	int x;
-	
-	prefSynchronize();
-	
-	if (prefIntRead(CALIBRATED_NAME, &thisSuccess) && thisSuccess) {
-		// Calibrated. Set all values from saved values.
-		allSuccess = YES;
-		for (x = 0; x < 3; x++) {
-			zeros[x] = prefFloatRead(ZERO_NAME(x), &thisSuccess);
-			allSuccess &= thisSuccess;
-			onegs[x] = prefFloatRead(ONEG_NAME(x), &thisSuccess);
-			allSuccess &= thisSuccess;
-		}
-		return allSuccess;
-	}
-	
-	return NO;
-}
-
-// Stores the current calibration into the stored preferences.
-static void storeCalibration(void) {
-	int x;
-	prefIntWrite(CALIBRATED_NAME, 1);
-	for (x = 0; x < 3; x++) {
-		prefFloatWrite(ZERO_NAME(x), zeros[x]);
-		prefFloatWrite(ONEG_NAME(x), onegs[x]);
-	}	
-	prefSynchronize();
-}
-
-
-// Sets the calibration to its default values.
-void defaultCalibration(void) {
-	int x;
-	for (x = 0; x < 3; x++) {
-		zeros[x] = sensors[sensorNum].axes[x].zerog;
-		onegs[x] = sensors[sensorNum].axes[x].oneg;
-	}
-}
-
-// Deletes the stored preferences.
-static void deleteCalibration(void) {
-	int x;
-	
-	prefDelete(CALIBRATED_NAME);
-	for (x = 0; x < 3; x++) {
-		prefDelete(ZERO_NAME(x));
-		prefDelete(ONEG_NAME(x));
-	}
-	prefSynchronize();
-}
-
-// Read a named floating point value from the stored preferences. Sets
-// the success boolean based on, you guessed it, whether it succeeds.
-static float prefFloatRead(NSString *prefName, BOOL *success) {
-	float result = 0.0f;
-	
-	CFPropertyListRef ref = CFPreferencesCopyAppValue((CFStringRef)prefName, 
-													   APP_ID);
-	// If there isn't such a preference, fail
-	if (ref == NULL) {
-		*success = NO;
-		return result;
-	}
-	CFTypeID typeID = CFGetTypeID(ref);
-	// Is it a number?
-	if (typeID == CFNumberGetTypeID()) {
-		// Is it a floating point number?
-		if (CFNumberIsFloatType((CFNumberRef)ref)) {
-			// Yup: grab it.
-			*success = CFNumberGetValue((__CFNumber*)ref, kCFNumberFloat32Type, &result);
-		} else {
-			// Nope: grab as an integer, and convert to a float.
-			long num;
-			if (CFNumberGetValue((CFNumberRef)ref, kCFNumberLongType, &num)) {
-				result = num;
-				*success = YES;
-			} else {
-				*success = NO;
-			}
-		}
-	// Or is it a string (e.g. set by the command line "defaults" command)?
-	} else if (typeID == CFStringGetTypeID()) {
-		result = (float)CFStringGetDoubleValue((CFStringRef)ref);
-		*success = YES;
-	} else {
-		// Can't convert to a number: fail.
-		*success = NO;
-	}
-	CFRelease(ref);
-	return result;
-}
-
-// Writes a named floating point value to the stored preferences.
-static void prefFloatWrite(NSString *prefName, float prefValue) {
-	CFNumberRef cfFloat = CFNumberCreate(kCFAllocatorDefault,
-										 kCFNumberFloatType,
-										 &prefValue);
-	CFPreferencesSetAppValue((CFStringRef)prefName,
-							 cfFloat,
-							 APP_ID);
-	CFRelease(cfFloat);
-}
-
-// Reads a named integer value from the stored preferences.
-static int prefIntRead(NSString *prefName, BOOL *success) {
-	Boolean internalSuccess;
-	CFIndex result = CFPreferencesGetAppIntegerValue((CFStringRef)prefName,
-													 APP_ID, 
-													 &internalSuccess);
-	*success = internalSuccess;
-	
-	return result;
-}
-
-// Writes a named integer value to the stored preferences.
-static void prefIntWrite(NSString *prefName, int prefValue) {
-	CFPreferencesSetAppValue((CFStringRef)prefName,
-							 (CFNumberRef)[NSNumber numberWithInt:prefValue],
-							 APP_ID);
-}
-
-// Deletes the named preference values.
-static void prefDelete(NSString *prefName) {
-		CFPreferencesSetAppValue((CFStringRef)prefName,
-								 NULL,
-								 APP_ID);
-}
-
-// Synchronizes the local preferences with the stored preferences.
-static void prefSynchronize(void) {
-	CFPreferencesAppSynchronize(APP_ID);
-}
-
-// Internal version of accelGetData, with logging
-int getData(sms_acceleration *accel, int calibrated, id logObject, SEL logSelector) {
-	IOItemCount iSize = recordSize;
-	IOByteCount oSize = recordSize;
-	kern_return_t result;
-	
-	if (running == NO) {
-		return -1;
-	}
-	
-	memset(iRecord, 1, iSize);
-	memset(oRecord, 0, oSize);
-	
-	LOG_2ARG(@"    Querying device: ", 
-			 sensors[sensorNum].function, sensors[sensorNum].recordSize);
-	
-#if __MAC_OS_X_VERSION_MIN_REQUIRED  >= 1050
-	const size_t InStructSize = recordSize;
-	size_t OutStructSize = recordSize;
-	result = IOConnectCallStructMethod(connection,
-						function,				// magic kernel function number
-						(const void *)iRecord,
-						InStructSize,
-						(void *)oRecord,
-						&OutStructSize
-					);
-#else // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
-	result = IOConnectMethodStructureIStructureO(connection,
-						function,				// magic kernel function number
-						iSize,
-						&oSize,
-						iRecord,
-						oRecord
-					);
-#endif // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
-
-	if (result != KERN_SUCCESS) {
-		LOG(@"failed.\n");
-		running = NO;
-		return result;
-	} else {
-		LOG(@"succeeded.\n");
-		
-		accel->x = getAxis(0, calibrated);
-		accel->y = getAxis(1, calibrated);
-		accel->z = getAxis(2, calibrated);
-		return 0;
-	}
-}
-
-// Given the returned record, extracts the value of the given axis. If
-// calibrated, then zero G is 0.0, and one G is 1.0.
-float getAxis(int which, int calibrated) {
-	// Get various values (to make code cleaner)
-	int indx = sensors[sensorNum].axes[which].index;
-	int size = sensors[sensorNum].axes[which].size;
-	float zerog = zeros[which];
-	float oneg = onegs[which];
-	// Storage for value to be returned
-	int value = 0;
-	
-	// Although the values in the returned record should have the proper
-	// endianness, we still have to get it into the proper end of value.
-#if (BYTE_ORDER == BIG_ENDIAN)
-	// On PowerPC processors
-	memcpy(((char *)&value) + (sizeof(int) - size), &oRecord[indx], size);
-#endif
-#if (BYTE_ORDER == LITTLE_ENDIAN)
-	// On Intel processors
-	memcpy(&value, &oRecord[indx], size);
-#endif
-	
-	value = signExtend(value, size);
-	
-	if (calibrated) {
-		// Scale and shift for zero.
-		return ((float)(value - zerog)) / oneg;
-	} else {
-		return value;
-	}
-}
-
-// Extends the sign, given the length of the value.
-int signExtend(int value, int size) {
-	// Extend sign
-	switch (size) {
-		case 1:
-			if (value & 0x00000080)
-				value |= 0xffffff00;
-			break;
-		case 2:
-			if (value & 0x00008000)
-				value |= 0xffff0000;
-			break;
-		case 3:
-			if (value & 0x00800000)
-				value |= 0xff000000;
-			break;
-	}
-	return value;
-}
-
-// Returns the model name of the computer (e.g. "MacBookPro1,1")
-NSString *getModelName(void) {
-	char model[32];
-	size_t len = sizeof(model);
-	int name[2] = {CTL_HW, HW_MODEL};
-	NSString *result;
-	
-	if (sysctl(name, 2, &model, &len, NULL, 0) == 0) {
-		result = [NSString stringWithFormat:@"%s", model];
-	} else {
-		result = @"";
-	}
-	
-	return result;
-}
-
-// Returns the current OS X version and build (e.g. "10.4.7 (build 8J2135a)")
-NSString *getOSVersion(void) {
-	NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:
-		@"/System/Library/CoreServices/SystemVersion.plist"];
-	NSString *versionString = [dict objectForKey:@"ProductVersion"];
-	NSString *buildString = [dict objectForKey:@"ProductBuildVersion"];
-	NSString *wholeString = [NSString stringWithFormat:@"%@ (build %@)", 
-		versionString, buildString];
-	return wholeString;
-}
-
-// Returns time within the current second in microseconds.
-// long getMicroseconds() {
-//	struct timeval t;
-//	gettimeofday(&t, 0);
-//	return t.tv_usec;
-//}
-
-// Returns fake data given the time. Range is +/-1.
-float fakeData(NSTimeInterval time) {
-	long secs = lround(floor(time));
-	int secsMod3 = secs % 3;
-	double angle = time * 10 * M_PI * 2;
-	double mag = exp(-(time - (secs - secsMod3)) * 2);
-	return sin(angle) * mag;
-}
-	
--- a/dom/system/nsDeviceMotion.cpp
+++ b/dom/system/nsDeviceMotion.cpp
@@ -39,24 +39,21 @@
 #include "nsAutoPtr.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIServiceManager.h"
 #include "nsIPrivateDOMEvent.h"
+#include "nsIDOMDeviceOrientationEvent.h"
+#include "nsIDOMDeviceMotionEvent.h"
 #include "nsIServiceManager.h"
 #include "nsIPrefService.h"
-
-using mozilla::TimeStamp;
-using mozilla::TimeDuration;
-
-// also see sDefaultSensorHint in mobile/android/base/GeckoAppShell.java
-#define DEFAULT_SENSOR_POLL 100
+#include "nsDOMDeviceMotionEvent.h"
 
 static const nsTArray<nsIDOMWindow*>::index_type NoIndex =
     nsTArray<nsIDOMWindow*>::NoIndex;
 
 class nsDeviceMotionData : public nsIDeviceMotionData
 {
 public:
   NS_DECL_ISUPPORTS
@@ -115,22 +112,28 @@ NS_IMETHODIMP nsDeviceMotionData::GetZ(d
   *aZ = mZ;
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS2(nsDeviceMotion, nsIDeviceMotion, nsIDeviceMotionUpdate)
 
 nsDeviceMotion::nsDeviceMotion()
 : mStarted(false),
+  mUpdateInterval(50), /* default to 50 ms */
   mEnabled(true)
 {
   nsCOMPtr<nsIPrefBranch> prefSrv = do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (prefSrv) {
+    PRInt32 value;
+    nsresult rv = prefSrv->GetIntPref("device.motion.update.interval", &value);
+    if (NS_SUCCEEDED(rv))
+      mUpdateInterval = value;
+
     bool bvalue;
-    nsresult rv = prefSrv->GetBoolPref("device.motion.enabled", &bvalue);
+    rv = prefSrv->GetBoolPref("device.motion.enabled", &bvalue);
     if (NS_SUCCEEDED(rv) && bvalue == false)
       mEnabled = false;
   }
 }
 
 nsDeviceMotion::~nsDeviceMotion()
 {
   if (mTimeoutTimer)
@@ -247,85 +250,25 @@ nsDeviceMotion::DeviceMotionChanged(PRUi
         pwindow->GetOuterWindow()->IsBackground())
       continue;
 
     nsCOMPtr<nsIDOMDocument> domdoc;
     windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
 
     if (domdoc) {
       nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
-      if (type == nsIDeviceMotionData::TYPE_ACCELERATION || 
-        type == nsIDeviceMotionData::TYPE_LINEAR_ACCELERATION || 
-        type == nsIDeviceMotionData::TYPE_GYROSCOPE )
-        FireDOMMotionEvent(domdoc, target, type, x, y, z);
+      if (type == nsIDeviceMotionData::TYPE_ACCELERATION)
+        FireDOMMotionEvent(domdoc, target, x, y, z);
       else if (type == nsIDeviceMotionData::TYPE_ORIENTATION)
         FireDOMOrientationEvent(domdoc, target, x, y, z);
     }
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDeviceMotion::NeedsCalibration()
-{
-  if (!mEnabled)
-    return NS_ERROR_NOT_INITIALIZED;
-
-  nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
-  for (PRUint32 i = listeners.Count(); i > 0 ; ) {
-    --i;
-    listeners[i]->NeedsCalibration();
-  }
-
-  nsCOMArray<nsIDOMWindow> windowListeners;
-  for (PRUint32 i = 0; i < mWindowListeners.Length(); i++) {
-    windowListeners.AppendObject(mWindowListeners[i]);
-  }
-
-  for (PRUint32 i = windowListeners.Count(); i > 0 ; ) {
-    --i;
-
-    // check to see if this window is in the background.  if
-    // it is, don't send any device motion to it.
-    nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(windowListeners[i]);
-    if (!pwindow ||
-        !pwindow->GetOuterWindow() ||
-        pwindow->GetOuterWindow()->IsBackground())
-      continue;
-
-    nsCOMPtr<nsIDOMDocument> domdoc;
-    windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
-
-    if (domdoc) {
-	nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
-        FireNeedsCalibration(domdoc, target);
-    }
-  }
-
-  return NS_OK;
-}
-
-void
-nsDeviceMotion::FireNeedsCalibration(nsIDOMDocument *domdoc,
-				    nsIDOMEventTarget *target)
-{
-  nsCOMPtr<nsIDOMEvent> event;
-  domdoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
-  if (!event)
-    return;
-
-  event->InitEvent(NS_LITERAL_STRING("compassneedscalibration"), true, false);
-  nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
-  if (privateEvent)
-    privateEvent->SetTrusted(true);
-  
-  bool defaultActionEnabled = true;
-  target->DispatchEvent(event, &defaultActionEnabled);
-}
-
 void
 nsDeviceMotion::FireDOMOrientationEvent(nsIDOMDocument *domdoc,
                                         nsIDOMEventTarget *target,
                                         double alpha,
                                         double beta,
                                         double gamma)
 {
   nsCOMPtr<nsIDOMEvent> event;
@@ -352,62 +295,39 @@ nsDeviceMotion::FireDOMOrientationEvent(
   
   target->DispatchEvent(event, &defaultActionEnabled);
 }
 
 
 void
 nsDeviceMotion::FireDOMMotionEvent(nsIDOMDocument *domdoc,
                                    nsIDOMEventTarget *target,
-                                   PRUint32 type,
                                    double x,
                                    double y,
                                    double z) {
-  // Attempt to coalesce events
-  bool fireEvent = TimeStamp::Now() > mLastDOMMotionEventTime + TimeDuration::FromMilliseconds(DEFAULT_SENSOR_POLL);
-
-  switch (type) {
-  case nsIDeviceMotionData::TYPE_LINEAR_ACCELERATION:
-      mLastAcceleration = new nsDOMDeviceAcceleration(x, y, z);
-      break;
-  case nsIDeviceMotionData::TYPE_ACCELERATION:
-      mLastAccelerationIncluduingGravity = new nsDOMDeviceAcceleration(x, y, z);
-      break;
-  case nsIDeviceMotionData::TYPE_GYROSCOPE:
-      mLastRotationRate = new nsDOMDeviceRotationRate(x, y, z);
-      break;
-  }
-
-  if (!fireEvent && (!mLastAcceleration || !mLastAccelerationIncluduingGravity || !mLastRotationRate)) {
-      return;
-  }
-
   nsCOMPtr<nsIDOMEvent> event;
+  bool defaultActionEnabled = true;
   domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event));
 
   nsCOMPtr<nsIDOMDeviceMotionEvent> me = do_QueryInterface(event);
 
   if (!me) {
     return;
-  }
+}
+
+  // Currently acceleration as determined includes gravity.
+  nsRefPtr<nsDOMDeviceAcceleration> acceleration = new nsDOMDeviceAcceleration(x, y, z);
 
   me->InitDeviceMotionEvent(NS_LITERAL_STRING("devicemotion"),
                             true,
                             false,
-                            mLastAcceleration,
-                            mLastAccelerationIncluduingGravity,
-                            mLastRotationRate,
-                            DEFAULT_SENSOR_POLL);
+                            nsnull,
+                            acceleration,
+                            nsnull,
+                            0);
 
   nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
   if (privateEvent)
     privateEvent->SetTrusted(true);
   
-  bool defaultActionEnabled = true;
   target->DispatchEvent(event, &defaultActionEnabled);
-
-  mLastRotationRate = nsnull;
-  mLastAccelerationIncluduingGravity = nsnull;
-  mLastAcceleration = nsnull;
-  mLastDOMMotionEventTime = TimeStamp::Now();
-
 }
 
--- a/dom/system/nsDeviceMotion.h
+++ b/dom/system/nsDeviceMotion.h
@@ -38,20 +38,16 @@
 #define nsDeviceMotion_h
 
 #include "nsIDeviceMotion.h"
 #include "nsIDOMDeviceMotionEvent.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
-#include "nsIDOMDeviceOrientationEvent.h"
-#include "nsIDOMDeviceMotionEvent.h"
-#include "nsDOMDeviceMotionEvent.h"
-#include "mozilla/TimeStamp.h"
 
 #define NS_DEVICE_MOTION_CID \
 { 0xecba5203, 0x77da, 0x465a, \
 { 0x86, 0x5e, 0x78, 0xb7, 0xaf, 0x10, 0xd8, 0xf7 } }
 
 #define NS_DEVICE_MOTION_CONTRACTID "@mozilla.org/devicemotion;1"
 
 class nsIDOMWindow;
@@ -75,36 +71,28 @@ private:
 
   bool mStarted;
 
   nsCOMPtr<nsITimer> mTimeoutTimer;
   static void TimeoutHandler(nsITimer *aTimer, void *aClosure);
 
  protected:
 
-  void FireNeedsCalibration(nsIDOMDocument *domdoc,
-			    nsIDOMEventTarget *target);
-
   void FireDOMOrientationEvent(class nsIDOMDocument *domDoc, 
                                class nsIDOMEventTarget *target,
                                double alpha,
                                double beta,
                                double gamma);
 
   void FireDOMMotionEvent(class nsIDOMDocument *domDoc, 
                           class nsIDOMEventTarget *target,
-                          PRUint32 type,
                           double x,
                           double y,
                           double z);
 
+  PRUint32 mUpdateInterval;
+  bool     mEnabled;
+
   virtual void Startup()  = 0;
   virtual void Shutdown() = 0;
-
-  bool mEnabled;
-  mozilla::TimeStamp mLastDOMMotionEventTime;
-  nsRefPtr<nsDOMDeviceAcceleration> mLastAcceleration;
-  nsRefPtr<nsDOMDeviceAcceleration> mLastAccelerationIncluduingGravity;
-  nsRefPtr<nsDOMDeviceRotationRate> mLastRotationRate;
-
 };
 
 #endif
--- a/dom/system/unix/Makefile.in
+++ b/dom/system/unix/Makefile.in
@@ -77,12 +77,9 @@ CPPSRCS         += $(MOCSRCS) \
                    nsQTMDeviceMotionSystem.cpp \
                    $(NULL)
 LOCAL_INCLUDES  += $(MOZ_QT_CFLAGS) \
                    -I$(topsrcdir)/dom/src/geolocation \
                    $(NULL)
 endif
 endif
 
-# We fire the nsDOMDeviceAcceleration
-LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
-
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/unix/nsDeviceMotionSystem.cpp
+++ b/dom/system/unix/nsDeviceMotionSystem.cpp
@@ -37,18 +37,16 @@
 
 #include <unistd.h>
 
 #include "mozilla/Util.h"
 
 #include "nsDeviceMotionSystem.h"
 #include "nsIServiceManager.h"
 
-#define DEFAULT_SENSOR_POLL 100
-
 using namespace mozilla;
 
 typedef struct {
   const char* mPosition;
   const char* mCalibrate;
   nsAccelerometerSystemDriver mToken;
 } AccelerometerData;
 
@@ -220,17 +218,17 @@ void nsDeviceMotionSystem::Startup()
 
   if (mType == eNoSensor)
     return;
 
   mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
   if (mUpdateTimer)
     mUpdateTimer->InitWithFuncCallback(UpdateHandler,
                                        this,
-                                       DEFAULT_SENSOR_POLL,
+                                       mUpdateInterval,
                                        nsITimer::TYPE_REPEATING_SLACK);
 }
 
 void nsDeviceMotionSystem::Shutdown()
 {
   if (mPositionFile) {
     fclose(mPositionFile);
     mPositionFile = nsnull;
--- a/dom/system/windows/Makefile.in
+++ b/dom/system/windows/Makefile.in
@@ -44,19 +44,16 @@ include $(DEPTH)/config/autoconf.mk
 MODULE      = dom
 LIBRARY_NAME    = domsystemwindows_s
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
-# We fire the nsDOMDeviceAcceleration
-LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
-
 include $(topsrcdir)/config/config.mk
 
 CPPSRCS     = \
         nsDeviceMotionSystem.cpp \
         nsHapticFeedback.cpp \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/system/windows/nsDeviceMotionSystem.cpp
+++ b/dom/system/windows/nsDeviceMotionSystem.cpp
@@ -34,18 +34,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsDeviceMotionSystem.h"
 #include "nsIServiceManager.h"
 #include "windows.h"
 
-#define DEFAULT_SENSOR_POLL 100
-
 ////////////////////////////
 // ThinkPad
 ////////////////////////////
 
 typedef struct {
   int status; // Current internal state
   unsigned short x; // raw value
   unsigned short y; // raw value
@@ -153,17 +151,17 @@ void nsDeviceMotionSystem::Startup()
     mSensor = nsnull;
     return;
   }
 
   mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
   if (mUpdateTimer)
     mUpdateTimer->InitWithFuncCallback(UpdateHandler,
                                        this,
-                                       DEFAULT_SENSOR_POLL,
+                                       mUpdateInterval,
                                        nsITimer::TYPE_REPEATING_SLACK);
 }
 
 void nsDeviceMotionSystem::Shutdown()
 {
   if (mUpdateTimer) {
     mUpdateTimer->Cancel();
     mUpdateTimer = nsnull;
--- a/embedding/android/GeckoEvent.java
+++ b/embedding/android/GeckoEvent.java
@@ -247,19 +247,20 @@ public class GeckoEvent {
             mType = PROXIMITY_EVENT;
             mDistance = s.values[0];
             Log.i("GeckoEvent", "SensorEvent type = " + s.sensor.getType() + 
                   " " + s.sensor.getName() + " " + mDistance);
             break;
         }
     }
 
-    public GeckoEvent(Location l) {
+    public GeckoEvent(Location l, Address a) {
         mType = LOCATION_EVENT;
         mLocation = l;
+        mAddress  = a;
     }
 
     public GeckoEvent(int imeAction, int offset, int count) {
         mType = IME_EVENT;
         mAction = imeAction;
         mOffset = offset;
         mCount = count;
     }
--- a/embedding/android/GeckoSurfaceView.java
+++ b/embedding/android/GeckoSurfaceView.java
@@ -575,20 +575,57 @@ class GeckoSurfaceView
     {
     }
 
     public void onSensorChanged(SensorEvent event)
     {
         GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
     }
 
+    private class GeocoderTask extends AsyncTask<Location, Void, Void> {
+        protected Void doInBackground(Location... location) {
+            try {
+                List<Address> addresses = mGeocoder.getFromLocation(location[0].getLatitude(),
+                                                                    location[0].getLongitude(), 1);
+                // grab the first address.  in the future,
+                // may want to expose multiple, or filter
+                // for best.
+                mLastGeoAddress = addresses.get(0);
+                GeckoAppShell.sendEventToGecko(new GeckoEvent(location[0], mLastGeoAddress));
+            } catch (Exception e) {
+                Log.w(LOG_FILE_NAME, "GeocoderTask "+e);
+            }
+            return null;
+        }
+    }
+
     // geolocation
     public void onLocationChanged(Location location)
     {
-        GeckoAppShell.sendEventToGecko(new GeckoEvent(location));
+        if (mGeocoder == null)
+            mGeocoder = new Geocoder(getContext(), Locale.getDefault());
+
+        if (mLastGeoAddress == null) {
+            new GeocoderTask().execute(location);
+        }
+        else {
+            float[] results = new float[1];
+            Location.distanceBetween(location.getLatitude(),
+                                     location.getLongitude(),
+                                     mLastGeoAddress.getLatitude(),
+                                     mLastGeoAddress.getLongitude(),
+                                     results);
+            // pfm value.  don't want to slam the
+            // geocoder with very similar values, so
+            // only call after about 100m
+            if (results[0] > 100)
+                new GeocoderTask().execute(location);
+        }
+
+        GeckoAppShell.sendEventToGecko(new GeckoEvent(location, mLastGeoAddress));
     }
 
     public void onProviderDisabled(String provider)
     {
     }
 
     public void onProviderEnabled(String provider)
     {
@@ -783,11 +820,14 @@ class GeckoSurfaceView
     String mIMEActionHint;
     boolean mIMELandscapeFS;
 
     // Software rendering
     Bitmap mSoftwareBitmap;
     ByteBuffer mSoftwareBuffer;
     Bitmap mSoftwareBufferCopy;
 
+    Geocoder mGeocoder;
+    Address  mLastGeoAddress;
+
     final SynchronousQueue<Object> mSyncDraws = new SynchronousQueue<Object>();
 }
 
--- a/hal/HalSensor.h
+++ b/hal/HalSensor.h
@@ -49,18 +49,16 @@ namespace hal {
  * Enumeration of sensor types.  They are used to specify type while
  * register or unregister an observer for a sensor of given type.
  */
 enum SensorType {
   SENSOR_UNKNOWN = -1,
   SENSOR_ORIENTATION,
   SENSOR_ACCELERATION,
   SENSOR_PROXIMITY,
-  SENSOR_LINEAR_ACCELERATION,
-  SENSOR_GYROSCOPE,
   NUM_SENSOR_TYPE
 };
 
 class SensorData;
 
 typedef Observer<SensorData> ISensorObserver;
 
 }
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -134,16 +134,18 @@ abstract public class GeckoApp
     private BroadcastReceiver mConnectivityReceiver;
     private BroadcastReceiver mBatteryReceiver;
 
     public static BrowserToolbar mBrowserToolbar;
     public static DoorHangerPopup mDoorHangerPopup;
     public static FormAssistPopup mFormAssistPopup;
     public Favicons mFavicons;
 
+    private Geocoder mGeocoder;
+    private Address  mLastGeoAddress;
     private static LayerController mLayerController;
     private static PlaceholderLayerClient mPlaceholderLayerClient;
     private static GeckoSoftwareLayerClient mSoftwareLayerClient;
     private AboutHomeContent mAboutHomeContent;
     private static AbsoluteLayout mPluginContainer;
 
     public String mLastTitle;
     public String mLastSnapshotUri;
@@ -2603,32 +2605,69 @@ abstract public class GeckoApp
     }
 
     public GeckoSoftwareLayerClient getSoftwareLayerClient() { return mSoftwareLayerClient; }
     public LayerController getLayerController() { return mLayerController; }
 
     // accelerometer
     public void onAccuracyChanged(Sensor sensor, int accuracy)
     {
-        Log.w(LOGTAG, "onAccuracyChanged "+accuracy);
-        GeckoAppShell.sendEventToGecko(GeckoEvent.createSensorAccuracyEvent(accuracy));
     }
 
     public void onSensorChanged(SensorEvent event)
     {
         Log.w(LOGTAG, "onSensorChanged "+event);
         GeckoAppShell.sendEventToGecko(GeckoEvent.createSensorEvent(event));
     }
 
+    private class GeocoderRunnable implements Runnable {
+        Location mLocation;
+        GeocoderRunnable (Location location) {
+            mLocation = location;
+        }
+        public void run() {
+            try {
+                List<Address> addresses = mGeocoder.getFromLocation(mLocation.getLatitude(),
+                                                                    mLocation.getLongitude(), 1);
+                // grab the first address.  in the future,
+                // may want to expose multiple, or filter
+                // for best.
+                mLastGeoAddress = addresses.get(0);
+                GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(mLocation, mLastGeoAddress));
+            } catch (Exception e) {
+                Log.w(LOGTAG, "GeocoderTask "+e);
+            }
+        }
+    }
+
     // geolocation
     public void onLocationChanged(Location location)
     {
         Log.w(LOGTAG, "onLocationChanged "+location);
-
-        GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location));
+        if (mGeocoder == null)
+            mGeocoder = new Geocoder(mLayerController.getView().getContext(), Locale.getDefault());
+
+        if (mLastGeoAddress == null) {
+            GeckoAppShell.getHandler().post(new GeocoderRunnable(location));
+        }
+        else {
+            float[] results = new float[1];
+            Location.distanceBetween(location.getLatitude(),
+                                     location.getLongitude(),
+                                     mLastGeoAddress.getLatitude(),
+                                     mLastGeoAddress.getLongitude(),
+                                     results);
+            // pfm value.  don't want to slam the
+            // geocoder with very similar values, so
+            // only call after about 100m
+            if (results[0] > 100)
+                GeckoAppShell.getHandler().post(new GeocoderRunnable(location));
+        }
+
+        GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location, mLastGeoAddress));
     }
 
     public void onProviderDisabled(String provider)
     {
     }
 
     public void onProviderEnabled(String provider)
     {
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -121,25 +121,16 @@ public class GeckoAppShell
     /* Is the value in sVibrationEndTime valid? */
     private static boolean sVibrationMaybePlaying = false;
 
     /* Time (in System.nanoTime() units) when the currently-playing vibration
      * is scheduled to end.  This value is valid only when
      * sVibrationMaybePlaying is true. */
     private static long sVibrationEndTime = 0;
 
-    /* Default value of how fast we should hint the Android sensors. */
-    private static int sDefaultSensorHint = 100;
-
-    private static Sensor gAccelerometerSensor = null;
-    private static Sensor gLinearAccelerometerSensor = null;
-    private static Sensor gGyroscopeSensor = null;
-    private static Sensor gOrientationSensor = null;
-    private static Sensor gProximitySensor = null;
-
     /* The Android-side API: API methods that Android calls */
 
     // Initialization methods
     public static native void nativeInit();
     public static native void nativeRun(String args);
 
     // helper methods
     //    public static native void setSurfaceView(GeckoSurfaceView sv);
@@ -537,16 +528,41 @@ public class GeckoAppShell
 
     // Signal the Java thread that it's time to wake up
     public static void acknowledgeEventSync() {
         CountDownLatch tmp = sGeckoPendingAcks;
         if (tmp != null)
             tmp.countDown();
     }
 
+    static Sensor gAccelerometerSensor = null;
+    static Sensor gOrientationSensor = null;
+
+    public static void enableDeviceMotion(boolean enable) {
+        LayerView v = GeckoApp.mAppContext.getLayerController().getView();
+        SensorManager sm = (SensorManager) v.getContext().getSystemService(Context.SENSOR_SERVICE);
+
+        if (gAccelerometerSensor == null || gOrientationSensor == null) {
+            gAccelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+            gOrientationSensor   = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
+        }
+
+        if (enable) {
+            if (gAccelerometerSensor != null)
+                sm.registerListener(GeckoApp.mAppContext, gAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME);
+            if (gOrientationSensor != null)
+                sm.registerListener(GeckoApp.mAppContext, gOrientationSensor,   SensorManager.SENSOR_DELAY_GAME);
+        } else {
+            if (gAccelerometerSensor != null)
+                sm.unregisterListener(GeckoApp.mAppContext, gAccelerometerSensor);
+            if (gOrientationSensor != null)
+                sm.unregisterListener(GeckoApp.mAppContext, gOrientationSensor);
+        }
+    }
+
     public static void enableLocation(final boolean enable) {
         getMainHandler().post(new Runnable() { 
                 public void run() {
                     LayerView v = GeckoApp.mAppContext.getLayerController().getView();
 
                     LocationManager lm = (LocationManager)
                         GeckoApp.mAppContext.getSystemService(Context.LOCATION_SERVICE);
 
@@ -564,87 +580,46 @@ public class GeckoAppShell
                         lm.requestLocationUpdates(provider, 100, (float).5, GeckoApp.mAppContext, l);
                     } else {
                         lm.removeUpdates(GeckoApp.mAppContext);
                     }
                 }
             });
     }
 
+    /*
+     * Keep these values consistent with |SensorType| in Hal.h
+     */
+    private static final int SENSOR_ORIENTATION = 1;
+    private static final int SENSOR_ACCELERATION = 2;
+    private static final int SENSOR_PROXIMITY = 3;
+
+    private static Sensor gProximitySensor = null;
+
     public static void enableSensor(int aSensortype) {
         SensorManager sm = (SensorManager)
             GeckoApp.mAppContext.getSystemService(Context.SENSOR_SERVICE);
 
         switch(aSensortype) {
-        case GeckoHalDefines.SENSOR_ORIENTATION:
-            if(gOrientationSensor == null)
-                gOrientationSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
-            if (gOrientationSensor != null)
-                sm.registerListener(GeckoApp.mAppContext, gOrientationSensor, sDefaultSensorHint);
-            break;
-
-        case GeckoHalDefines.SENSOR_ACCELERATION:
-            if(gAccelerometerSensor == null)
-                gAccelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
-            if (gAccelerometerSensor != null)
-                sm.registerListener(GeckoApp.mAppContext, gAccelerometerSensor, sDefaultSensorHint);
-            break;
-
-        case GeckoHalDefines.SENSOR_PROXIMITY:
+        case SENSOR_PROXIMITY:
             if(gProximitySensor == null)
                 gProximitySensor = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
-            if (gProximitySensor != null)
-                sm.registerListener(GeckoApp.mAppContext, gProximitySensor, sDefaultSensorHint);
+            sm.registerListener(GeckoApp.mAppContext, gProximitySensor,
+                                SensorManager.SENSOR_DELAY_GAME);
             break;
-
-        case GeckoHalDefines.SENSOR_LINEAR_ACCELERATION:
-            if(gLinearAccelerometerSensor == null)
-                gLinearAccelerometerSensor = sm.getDefaultSensor(10);
-            if (gLinearAccelerometerSensor != null)
-                sm.registerListener(GeckoApp.mAppContext, gLinearAccelerometerSensor, sDefaultSensorHint);
-            break;
-
-        case GeckoHalDefines.SENSOR_GYROSCOPE:
-            if(gGyroscopeSensor == null)
-                gGyroscopeSensor = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
-            if (gGyroscopeSensor != null)
-                sm.registerListener(GeckoApp.mAppContext, gGyroscopeSensor, sDefaultSensorHint);
-            break;
-
         }
     }
 
     public static void disableSensor(int aSensortype) {
         SensorManager sm = (SensorManager)
             GeckoApp.mAppContext.getSystemService(Context.SENSOR_SERVICE);
 
-        switch (aSensortype) {
-        case GeckoHalDefines.SENSOR_ORIENTATION:
-            if (gOrientationSensor != null)
-                sm.unregisterListener(GeckoApp.mAppContext, gOrientationSensor);
-            break;
-
-        case GeckoHalDefines.SENSOR_ACCELERATION:
-            if (gAccelerometerSensor != null)
-                sm.unregisterListener(GeckoApp.mAppContext, gAccelerometerSensor);
-            break;
-
-        case GeckoHalDefines.SENSOR_PROXIMITY:
-            if (gProximitySensor != null)
-                sm.unregisterListener(GeckoApp.mAppContext, gProximitySensor);
-            break;
-
-        case GeckoHalDefines.SENSOR_LINEAR_ACCELERATION:
-            if (gLinearAccelerometerSensor != null)
-                sm.unregisterListener(GeckoApp.mAppContext, gLinearAccelerometerSensor);
-            break;
-
-        case GeckoHalDefines.SENSOR_GYROSCOPE:
-            if (gGyroscopeSensor != null)
-                sm.unregisterListener(GeckoApp.mAppContext, gGyroscopeSensor);
+        switch(aSensortype) {
+        case SENSOR_PROXIMITY:
+            sm.unregisterListener(GeckoApp.mAppContext, gProximitySensor);
             break;
         }
     }
 
     public static void moveTaskToBack() {
         GeckoApp.mAppContext.moveTaskToBack(true);
     }
 
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -47,35 +47,34 @@ import android.graphics.*;
 import android.widget.*;
 import android.hardware.*;
 import android.location.*;
 import android.util.FloatMath;
 import android.util.DisplayMetrics;
 import android.graphics.PointF;
 import android.text.format.Time;
 import android.os.SystemClock;
-import java.lang.Math;
 import java.lang.System;
 
 import android.util.Log;
 
 /* We're not allowed to hold on to most events given to us
  * so we save the parts of the events we want to use in GeckoEvent.
  * Fields have different meanings depending on the event type.
  */
 
 public class GeckoEvent {
     private static final String LOGTAG = "GeckoEvent";
 
     private static final int INVALID = -1;
     private static final int NATIVE_POKE = 0;
     private static final int KEY_EVENT = 1;
     private static final int MOTION_EVENT = 2;
-    private static final int SENSOR_EVENT = 3;
-    private static final int UNUSED1_EVENT = 4;
+    private static final int ORIENTATION_EVENT = 3;
+    private static final int ACCELERATION_EVENT = 4;
     private static final int LOCATION_EVENT = 5;
     private static final int IME_EVENT = 6;
     private static final int DRAW = 7;
     private static final int SIZE_CHANGED = 8;
     private static final int ACTIVITY_STOPPING = 9;
     private static final int ACTIVITY_PAUSING = 10;
     private static final int ACTIVITY_SHUTDOWN = 11;
     private static final int LOAD_URI = 12;
@@ -85,17 +84,16 @@ public class GeckoEvent {
     private static final int ACTIVITY_START = 17;
     private static final int BROADCAST = 19;
     private static final int VIEWPORT = 20;
     private static final int VISITED = 21;
     private static final int NETWORK_CHANGED = 22;
     private static final int PROXIMITY_EVENT = 23;
     private static final int ACTIVITY_RESUMING = 24;
     private static final int SCREENSHOT = 25;
-    private static final int SENSOR_ACCURACY = 26;
 
     public static final int IME_COMPOSITION_END = 0;
     public static final int IME_COMPOSITION_BEGIN = 1;
     public static final int IME_SET_TEXT = 2;
     public static final int IME_GET_TEXT = 3;
     public static final int IME_DELETE_TEXT = 4;
     public static final int IME_SET_SELECTION = 5;
     public static final int IME_GET_SELECTION = 6;
@@ -117,16 +115,17 @@ public class GeckoEvent {
     public Point[] mPoints;
     public int[] mPointIndicies;
     public int mPointerIndex; // index of the point that has changed
     public float[] mOrientations;
     public float[] mPressures;
     public Point[] mPointRadii;
     public Rect mRect;
     public double mX, mY, mZ;
+    public double mAlpha, mBeta, mGamma;
     public double mDistance;
 
     public int mMetaState, mFlags;
     public int mKeyCode, mUnicodeChar;
     public int mOffset, mCount;
     public String mCharacters, mCharactersExtra;
     public int mRangeType, mRangeStyles;
     public int mRangeForeColor, mRangeBackColor;
@@ -275,66 +274,46 @@ public class GeckoEvent {
         } catch(Exception ex) {
             Log.e(LOGTAG, "Error creating motion point " + index, ex);
             mPointRadii[index] = new Point(0, 0);
             mPoints[index] = new Point(0, 0);
         }
     }
 
     public static GeckoEvent createSensorEvent(SensorEvent s) {
+        GeckoEvent event = null;
         int sensor_type = s.sensor.getType();
-        GeckoEvent event = null;
-
+ 
         switch(sensor_type) {
-
         case Sensor.TYPE_ACCELEROMETER:
-            event = new GeckoEvent(SENSOR_EVENT);
-            event.mFlags = GeckoHalDefines.SENSOR_ACCELERATION;
-            event.mX = s.values[0];
-            event.mY = s.values[1];
-            event.mZ = s.values[2];
-            break;
-
-        case 10 /* Requires API Level 9, so just use the raw value - Sensor.TYPE_LINEAR_ACCELEROMETER*/ :
-            event = new GeckoEvent(SENSOR_EVENT);
-            event.mFlags = GeckoHalDefines.SENSOR_LINEAR_ACCELERATION;
+            event = new GeckoEvent(ACCELERATION_EVENT);
             event.mX = s.values[0];
             event.mY = s.values[1];
             event.mZ = s.values[2];
             break;
-
+            
         case Sensor.TYPE_ORIENTATION:
-            event = new GeckoEvent(SENSOR_EVENT);
-            event.mFlags = GeckoHalDefines.SENSOR_ORIENTATION;
-            event.mX = s.values[0];
-            event.mY = s.values[1];
-            event.mZ = s.values[2];
-            break;
-
-        case Sensor.TYPE_GYROSCOPE:
-            event = new GeckoEvent(SENSOR_EVENT);
-            event.mFlags = GeckoHalDefines.SENSOR_GYROSCOPE;
-            event.mX = Math.toDegrees(s.values[0]);
-            event.mY = Math.toDegrees(s.values[1]);
-            event.mZ = Math.toDegrees(s.values[2]);
+            event = new GeckoEvent(ORIENTATION_EVENT);
+            event.mAlpha = -s.values[0];
+            event.mBeta = -s.values[1];
+            event.mGamma = -s.values[2];
             break;
 
         case Sensor.TYPE_PROXIMITY:
-            // bug 734854 - maybe we can get rid of this event.  is
-            // values[1] and values[2] valid?
             event = new GeckoEvent(PROXIMITY_EVENT);
             event.mDistance = s.values[0];
             break;
         }
         return event;
     }
 
-    public static GeckoEvent createLocationEvent(Location l) {
+    public static GeckoEvent createLocationEvent(Location l, Address a) {
         GeckoEvent event = new GeckoEvent(LOCATION_EVENT);
         event.mLocation = l;
+        event.mAddress  = a;
         return event;
     }
 
     public static GeckoEvent createIMEEvent(int imeAction, int offset, int count) {
         GeckoEvent event = new GeckoEvent(IME_EVENT);
         event.mAction = imeAction;
         event.mOffset = offset;
         event.mCount = count;
@@ -425,15 +404,9 @@ public class GeckoEvent {
     public static GeckoEvent createScreenshotEvent(int tabId, int sw, int sh, int dw, int dh) {
         GeckoEvent event = new GeckoEvent(SCREENSHOT);
         event.mPoints = new Point[2];
         event.mPoints[0] = new Point(sw, sh);
         event.mPoints[1] = new Point(dw, dh);
         event.mMetaState = tabId;
         return event;
     }
-
-    public static GeckoEvent createSensorAccuracyEvent(int accuracy) {
-        GeckoEvent event = new GeckoEvent(SENSOR_ACCURACY);
-        event.mFlags = accuracy;
-        return event;
-    }
 }
deleted file mode 100644
--- a/mobile/android/base/GeckoHalDefines.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * ***** 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 Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * 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 ***** */
-
-package org.mozilla.gecko;
-
-public class GeckoHalDefines
-{
-    /*
-     * Keep these values consistent with |SensorType| in Hal.h
-    */
-    public static final int SENSOR_ORIENTATION = 0;
-    public static final int SENSOR_ACCELERATION = 1;
-    public static final int SENSOR_PROXIMITY = 2;
-    public static final int SENSOR_LINEAR_ACCELERATION = 3;
-    public static final int SENSOR_GYROSCOPE = 4;
-};
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -82,17 +82,16 @@ FENNEC_JAVA_FILES = \
   GeckoAppShell.java \
   GeckoAsyncTask.java \
   GeckoBatteryManager.java \
   GeckoBackgroundThread.java \
   GeckoConnectivityReceiver.java \
   GeckoEvent.java \
   GeckoEventListener.java \
   GeckoEventResponder.java \
-  GeckoHalDefines.java \
   GeckoInputConnection.java \
 	GeckoMessageReceiver.java \
   GeckoPreferences.java \
   GeckoProfile.java \
   GeckoStateListDrawable.java \
   GeckoThread.java \
   GlobalHistory.java \
   LinkPreference.java \
--- a/toolkit/content/license.html
+++ b/toolkit/content/license.html
@@ -89,17 +89,16 @@
       <li><a href="about:license#msstdint">msstdint License</a></li>
       <li><a href="about:license#openvision">OpenVision License</a></li>
       <li><a href="about:license#qcms">qcms License</a></li>
       <li><a href="about:license#xdg">Red Hat xdg_user_dir_lookup License</a></li>
       <li><a href="about:license#hunspell-ru">Russian Spellchecking Dictionary License</a></li>
       <li><a href="about:license#skia">Skia License</a></li>
       <li><a href="about:license#snappy">Snappy License</a></li>
       <li><a href="about:license#sparkle">Sparkle License</a></li>
-      <li><a href="about:license#suitable">Suitable Systems License</a></li>
       <li><a href="about:license#sunsoft">SunSoft License</a></li>
       <li><a href="about:license#ucal">University of California License</a></li>      
       <li><a href="about:license#ucambridge">University of Cambridge License</a></li>      
       <li><a href="about:license#uszeged">University of Szeged License</a></li>      
       <li><a href="about:license#hunspell-en-US">US English Spellchecking Dictionary Licenses</a></li>
       <li><a href="about:license#v8">V8 License</a></li>
       <li><a href="about:license#xiph">Xiph.org Foundation License</a></li>
     </ul>
@@ -2230,69 +2229,16 @@ copies or substantial portions of the So
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 </pre>
 
-    <hr>
-
-    <h1><a id="suitable"></a>Suitable Systems License</h1>
-
-    <p>This license applies to certain files in the directory
-    <span class="path">dom/system/cocoa/</span>.</p>
-
-<pre>
-SMSLib Sudden Motion Sensor Access Library
-Copyright (c) 2010 Suitable Systems
-All rights reserved.
-
-Developed by: Daniel Griscom
-              Suitable Systems
-              http://www.suitable.com
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal with the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimers.
-
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimers in the
-documentation and/or other materials provided with the distribution.
-
-- Neither the names of Suitable Systems nor the names of its
-contributors may be used to endorse or promote products derived from
-this Software without specific prior written permission.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
-
-For more information about SMSLib, see
-	<http://www.suitable.com/tools/smslib.html>
-or contact
-	Daniel Griscom
-	Suitable Systems
-	1 Centre Street, Suite 204
-	Wakefield, MA 01880
-	(781) 665-0053
-</pre>
-
 
     <hr>
 
     <h1><a id="sunsoft"></a>SunSoft License</h1>
 
     <p>This license applies to the
       <span class="path">ICC_H</span> block in
       <span class="path">gfx/qcms/qcms.h</span>.</p>
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -106,19 +106,24 @@ AndroidBridge::Init(JNIEnv *jEnv,
     mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass);
 
     jNotifyIME = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIME", "(II)V");
     jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;Ljava/lang/String;Z)V");
     jNotifyIMEChange = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V");
     jNotifyScreenShot = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyScreenShot", "(Ljava/nio/ByteBuffer;III)V");
     jAcknowledgeEventSync = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "acknowledgeEventSync", "()V");
 
+    jEnableDeviceMotion = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableDeviceMotion", "(Z)V");
     jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V");
-    jEnableSensor = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableSensor", "(I)V");
-    jDisableSensor = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableSensor", "(I)V");
+    jEnableSensor =
+        (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass,
+                                            "enableSensor", "(I)V");
+    jDisableSensor =
+        (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass,
+                                            "disableSensor", "(I)V");
     jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V");
     jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V");
     jNotifyXreExit = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onXreExit", "()V");
     jGetHandlersForMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
     jGetHandlersForURL = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getHandlersForURL", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
     jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
     jGetMimeTypeFromExtensions = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
     jGetExtensionFromMimeType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getExtensionFromMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
@@ -301,65 +306,47 @@ AndroidBridge::AcknowledgeEventSync()
     env->CallStaticVoidMethod(mGeckoAppShellClass, jAcknowledgeEventSync);
 }
 
 void
 AndroidBridge::EnableDeviceMotion(bool aEnable)
 {
     ALOG_BRIDGE("AndroidBridge::EnableDeviceMotion");
 
-    // bug 734855 - we probably can make this finer grain based on
-    // the DOM APIs that are being invoked.
-    if (aEnable) {
-        EnableSensor(hal::SENSOR_ORIENTATION);
-        EnableSensor(hal::SENSOR_ACCELERATION);
-        EnableSensor(hal::SENSOR_LINEAR_ACCELERATION);
-        EnableSensor(hal::SENSOR_GYROSCOPE);
-    }
-    else {
-        DisableSensor(hal::SENSOR_ORIENTATION);
-        DisableSensor(hal::SENSOR_ACCELERATION);
-        DisableSensor(hal::SENSOR_LINEAR_ACCELERATION);
-        DisableSensor(hal::SENSOR_GYROSCOPE);
-    }
+    JNIEnv *env = GetJNIEnv();
+    if (!env)
+        return;
+
+    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableDeviceMotion, aEnable);
 }
 
-
 void
 AndroidBridge::EnableLocation(bool aEnable)
 {
     ALOG_BRIDGE("AndroidBridge::EnableLocation");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
-
-    AutoLocalJNIFrame jniFrame(env, 1);
+    
     env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableLocation, aEnable);
 }
 
 void
 AndroidBridge::EnableSensor(int aSensorType) {
     ALOG_BRIDGE("AndroidBridge::EnableSensor");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 1);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableSensor, aSensorType);
+    mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jEnableSensor,
+                                  aSensorType);
 }
 
 void
 AndroidBridge::DisableSensor(int aSensorType) {
     ALOG_BRIDGE("AndroidBridge::DisableSensor");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-    AutoLocalJNIFrame jniFrame(env, 1);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jDisableSensor, aSensorType);
+    mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jDisableSensor,
+                                  aSensorType);
 }
 
 void
 AndroidBridge::ReturnIMEQueryResult(const PRUnichar *aResult, PRUint32 aLen,
                                     int aSelStart, int aSelLen)
 {
     ALOG_BRIDGE("AndroidBridge::ReturnIMEQueryResult");
 
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -419,16 +419,17 @@ protected:
     nsCOMArray<nsIRunnable> mRunnableQueue;
 
     // other things
     jmethodID jNotifyIME;
     jmethodID jNotifyIMEEnabled;
     jmethodID jNotifyIMEChange;
     jmethodID jNotifyScreenShot;
     jmethodID jAcknowledgeEventSync;
+    jmethodID jEnableDeviceMotion;
     jmethodID jEnableLocation;
     jmethodID jEnableSensor;
     jmethodID jDisableSensor;
     jmethodID jReturnIMEQueryResult;
     jmethodID jNotifyAppShellReady;
     jmethodID jNotifyXreExit;
     jmethodID jScheduleRestart;
     jmethodID jGetOutstandingDrawEvents;
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -44,16 +44,19 @@ jclass AndroidGeckoEvent::jGeckoEventCla
 jfieldID AndroidGeckoEvent::jActionField = 0;
 jfieldID AndroidGeckoEvent::jTypeField = 0;
 jfieldID AndroidGeckoEvent::jTimeField = 0;
 jfieldID AndroidGeckoEvent::jPoints = 0;
 jfieldID AndroidGeckoEvent::jPointIndicies = 0;
 jfieldID AndroidGeckoEvent::jPressures = 0;
 jfieldID AndroidGeckoEvent::jPointRadii = 0;
 jfieldID AndroidGeckoEvent::jOrientations = 0;
+jfieldID AndroidGeckoEvent::jAlphaField = 0;
+jfieldID AndroidGeckoEvent::jBetaField = 0;
+jfieldID AndroidGeckoEvent::jGammaField = 0;
 jfieldID AndroidGeckoEvent::jXField = 0;
 jfieldID AndroidGeckoEvent::jYField = 0;
 jfieldID AndroidGeckoEvent::jZField = 0;
 jfieldID AndroidGeckoEvent::jDistanceField = 0;
 jfieldID AndroidGeckoEvent::jRectField = 0;
 jfieldID AndroidGeckoEvent::jNativeWindowField = 0;
 
 jfieldID AndroidGeckoEvent::jCharactersField = 0;
@@ -65,16 +68,17 @@ jfieldID AndroidGeckoEvent::jUnicodeChar
 jfieldID AndroidGeckoEvent::jOffsetField = 0;
 jfieldID AndroidGeckoEvent::jCountField = 0;
 jfieldID AndroidGeckoEvent::jPointerIndexField = 0;
 jfieldID AndroidGeckoEvent::jRangeTypeField = 0;
 jfieldID AndroidGeckoEvent::jRangeStylesField = 0;
 jfieldID AndroidGeckoEvent::jRangeForeColorField = 0;
 jfieldID AndroidGeckoEvent::jRangeBackColorField = 0;
 jfieldID AndroidGeckoEvent::jLocationField = 0;
+jfieldID AndroidGeckoEvent::jAddressField = 0;
 jfieldID AndroidGeckoEvent::jBandwidthField = 0;
 jfieldID AndroidGeckoEvent::jCanBeMeteredField = 0;
 
 jclass AndroidPoint::jPointClass = 0;
 jfieldID AndroidPoint::jXField = 0;
 jfieldID AndroidPoint::jYField = 0;
 
 jclass AndroidRect::jRectClass = 0;
@@ -87,16 +91,29 @@ jclass AndroidLocation::jLocationClass =
 jmethodID AndroidLocation::jGetLatitudeMethod = 0;
 jmethodID AndroidLocation::jGetLongitudeMethod = 0;
 jmethodID AndroidLocation::jGetAltitudeMethod = 0;
 jmethodID AndroidLocation::jGetAccuracyMethod = 0;
 jmethodID AndroidLocation::jGetBearingMethod = 0;
 jmethodID AndroidLocation::jGetSpeedMethod = 0;
 jmethodID AndroidLocation::jGetTimeMethod = 0;
 
+jclass AndroidAddress::jAddressClass = 0;
+jmethodID AndroidAddress::jGetAddressLineMethod;
+jmethodID AndroidAddress::jGetAdminAreaMethod;
+jmethodID AndroidAddress::jGetCountryNameMethod;
+jmethodID AndroidAddress::jGetFeatureNameMethod;
+jmethodID AndroidAddress::jGetLocalityMethod;
+jmethodID AndroidAddress::jGetPostalCodeMethod;
+jmethodID AndroidAddress::jGetPremisesMethod;
+jmethodID AndroidAddress::jGetSubAdminAreaMethod;
+jmethodID AndroidAddress::jGetSubLocalityMethod;
+jmethodID AndroidAddress::jGetSubThoroughfareMethod;
+jmethodID AndroidAddress::jGetThoroughfareMethod;
+
 jclass AndroidGeckoSoftwareLayerClient::jGeckoSoftwareLayerClientClass = 0;
 jmethodID AndroidGeckoSoftwareLayerClient::jLockBufferMethod = 0;
 jmethodID AndroidGeckoSoftwareLayerClient::jUnlockBufferMethod = 0;
 jmethodID AndroidGeckoSoftwareLayerClient::jBeginDrawingMethod = 0;
 jmethodID AndroidGeckoSoftwareLayerClient::jEndDrawingMethod = 0;
 jclass AndroidGeckoSurfaceView::jGeckoSurfaceViewClass = 0;
 jmethodID AndroidGeckoSurfaceView::jBeginDrawingMethod = 0;
 jmethodID AndroidGeckoSurfaceView::jEndDrawingMethod = 0;
@@ -120,16 +137,17 @@ jmethodID AndroidGeckoSurfaceView::jGetH
     ((jmethodID) jEnv->GetMethodID(jClass, fname, ftype))
 
 void
 mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv)
 {
     AndroidGeckoEvent::InitGeckoEventClass(jEnv);
     AndroidPoint::InitPointClass(jEnv);
     AndroidLocation::InitLocationClass(jEnv);
+    AndroidAddress::InitAddressClass(jEnv);
     AndroidRect::InitRectClass(jEnv);
     AndroidGeckoSoftwareLayerClient::InitGeckoSoftwareLayerClientClass(jEnv);
     AndroidGeckoSurfaceView::InitGeckoSurfaceViewClass(jEnv);
 }
 
 void
 AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
 {
@@ -140,16 +158,19 @@ AndroidGeckoEvent::InitGeckoEventClass(J
     jActionField = getField("mAction", "I");
     jTypeField = getField("mType", "I");
     jTimeField = getField("mTime", "J");
     jPoints = getField("mPoints", "[Landroid/graphics/Point;");
     jPointIndicies = getField("mPointIndicies", "[I");
     jOrientations = getField("mOrientations", "[F");
     jPressures = getField("mPressures", "[F");
     jPointRadii = getField("mPointRadii", "[Landroid/graphics/Point;");
+    jAlphaField = getField("mAlpha", "D");
+    jBetaField = getField("mBeta", "D");
+    jGammaField = getField("mGamma", "D");
     jXField = getField("mX", "D");
     jYField = getField("mY", "D");
     jZField = getField("mZ", "D");
     jDistanceField = getField("mDistance", "D");
     jRectField = getField("mRect", "Landroid/graphics/Rect;");
 
     jCharactersField = getField("mCharacters", "Ljava/lang/String;");
     jCharactersExtraField = getField("mCharactersExtra", "Ljava/lang/String;");
@@ -160,16 +181,17 @@ AndroidGeckoEvent::InitGeckoEventClass(J
     jOffsetField = getField("mOffset", "I");
     jCountField = getField("mCount", "I");
     jPointerIndexField = getField("mPointerIndex", "I");
     jRangeTypeField = getField("mRangeType", "I");
     jRangeStylesField = getField("mRangeStyles", "I");
     jRangeForeColorField = getField("mRangeForeColor", "I");
     jRangeBackColorField = getField("mRangeBackColor", "I");
     jLocationField = getField("mLocation", "Landroid/location/Location;");
+    jAddressField = getField("mAddress", "Landroid/location/Address;");
     jBandwidthField = getField("mBandwidth", "D");
     jCanBeMeteredField = getField("mCanBeMetered", "Z");
 }
 
 void
 AndroidGeckoSurfaceView::InitGeckoSurfaceViewClass(JNIEnv *jEnv)
 {
 #ifndef MOZ_JAVA_COMPOSITOR
@@ -198,16 +220,70 @@ AndroidLocation::InitLocationClass(JNIEn
     jGetLongitudeMethod = getMethod("getLongitude", "()D");
     jGetAltitudeMethod = getMethod("getAltitude", "()D");
     jGetAccuracyMethod = getMethod("getAccuracy", "()F");
     jGetBearingMethod = getMethod("getBearing", "()F");
     jGetSpeedMethod = getMethod("getSpeed", "()F");
     jGetTimeMethod = getMethod("getTime", "()J");
 }
 
+void
+AndroidAddress::InitAddressClass(JNIEnv *jEnv)
+{
+    initInit();
+
+    jAddressClass = getClassGlobalRef("android/location/Address");
+
+    jGetAddressLineMethod = getMethod("getAddressLine", "(I)Ljava/lang/String;");
+    jGetAdminAreaMethod = getMethod("getAdminArea", "()Ljava/lang/String;");
+    jGetCountryNameMethod = getMethod("getCountryName", "()Ljava/lang/String;");
+    jGetFeatureNameMethod = getMethod("getFeatureName", "()Ljava/lang/String;");
+    jGetLocalityMethod  = getMethod("getLocality", "()Ljava/lang/String;");
+    jGetPostalCodeMethod = getMethod("getPostalCode", "()Ljava/lang/String;");
+    jGetPremisesMethod = getMethod("getPremises", "()Ljava/lang/String;");
+    jGetSubAdminAreaMethod = getMethod("getSubAdminArea", "()Ljava/lang/String;");
+    jGetSubLocalityMethod = getMethod("getSubLocality", "()Ljava/lang/String;");
+    jGetSubThoroughfareMethod = getMethod("getSubThoroughfare", "()Ljava/lang/String;");
+    jGetThoroughfareMethod = getMethod("getThoroughfare", "()Ljava/lang/String;");
+}
+
+nsGeoPositionAddress*
+AndroidAddress::CreateGeoPositionAddress(JNIEnv *jenv, jobject jobj)
+{
+    nsJNIString streetNumber(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetSubThoroughfareMethod)), jenv);
+    nsJNIString street(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetThoroughfareMethod)), jenv);
+    nsJNIString city(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetLocalityMethod)), jenv);
+    nsJNIString county(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetSubAdminAreaMethod)), jenv);
+    nsJNIString country(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetCountryNameMethod)), jenv);
+    nsJNIString premises(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetPremisesMethod)), jenv);
+    nsJNIString postalCode(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetPostalCodeMethod)), jenv);
+    nsJNIString region(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetAdminAreaMethod, 0)), jenv);
+
+#ifdef DEBUG
+    printf_stderr("!!!!!!!!!!!!!! AndroidAddress::CreateGeoPositionAddress:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n",
+                  NS_LossyConvertUTF16toASCII(streetNumber).get(),
+                  NS_LossyConvertUTF16toASCII(street).get(),
+                  NS_LossyConvertUTF16toASCII(premises).get(),
+                  NS_LossyConvertUTF16toASCII(city).get(),
+                  NS_LossyConvertUTF16toASCII(county).get(),
+                  NS_LossyConvertUTF16toASCII(region).get(),
+                  NS_LossyConvertUTF16toASCII(country).get(),
+                  NS_LossyConvertUTF16toASCII(postalCode).get());
+#endif
+
+    return new nsGeoPositionAddress(streetNumber,
+                                    street,
+                                    premises,
+                                    city,
+                                    county,
+                                    region,
+                                    country,
+                                    postalCode);
+}
+
 nsGeoPosition*
 AndroidLocation::CreateGeoPosition(JNIEnv *jenv, jobject jobj)
 {
     double latitude  = jenv->CallDoubleMethod(jobj, jGetLatitudeMethod);
     double longitude = jenv->CallDoubleMethod(jobj, jGetLongitudeMethod);
     double altitude  = jenv->CallDoubleMethod(jobj, jGetAltitudeMethod);
     float  accuracy  = jenv->CallFloatMethod (jobj, jGetAccuracyMethod);
     float  bearing   = jenv->CallFloatMethod (jobj, jGetBearingMethod);
@@ -416,26 +492,35 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
                     jenv->GetIntField(jobj, jRangeBackColorField);
             }
             break;
 
         case DRAW:
             ReadRectField(jenv);
             break;
 
-        case SENSOR_EVENT:
-             mX = jenv->GetDoubleField(jobj, jXField);
-             mY = jenv->GetDoubleField(jobj, jYField);
-             mZ = jenv->GetDoubleField(jobj, jZField);
-             mFlags = jenv->GetIntField(jobj, jFlagsField);
-             break;
+        case ORIENTATION_EVENT:
+            mAlpha = jenv->GetDoubleField(jobj, jAlphaField);
+            mBeta = jenv->GetDoubleField(jobj, jBetaField);
+            mGamma = jenv->GetDoubleField(jobj, jGammaField);
+            break;
+
+       case ACCELERATION_EVENT:
+            mX = jenv->GetDoubleField(jobj, jXField);
+            mY = jenv->GetDoubleField(jobj, jYField);
+            mZ = jenv->GetDoubleField(jobj, jZField);
+            break;
 
         case LOCATION_EVENT: {
             jobject location = jenv->GetObjectField(jobj, jLocationField);
+            jobject address  = jenv->GetObjectField(jobj, jAddressField);
+
             mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location);
+            if (address)
+                mGeoAddress = AndroidAddress::CreateGeoPositionAddress(jenv, address);
             break;
         }
 
         case LOAD_URI: {
             ReadCharactersField(jenv);
             break;
         }
 
@@ -457,17 +542,16 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
             break;
         }
 
         case PROXIMITY_EVENT: {
             mDistance = jenv->GetDoubleField(jobj, jDistanceField);
             break;
         }
 
-        case SENSOR_ACCURACY:
         case ACTIVITY_STOPPING:
         case ACTIVITY_START:
         case ACTIVITY_PAUSING:
         case ACTIVITY_RESUMING: {
             mFlags = jenv->GetIntField(jobj, jFlagsField);
             break;
         }
 
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -379,16 +379,35 @@ public:
     static jmethodID jGetLongitudeMethod;
     static jmethodID jGetAltitudeMethod;
     static jmethodID jGetAccuracyMethod;
     static jmethodID jGetBearingMethod;
     static jmethodID jGetSpeedMethod;
     static jmethodID jGetTimeMethod;
 };
 
+class AndroidAddress : public WrappedJavaObject
+{
+public:
+    static void InitAddressClass(JNIEnv *jEnv);
+    static nsGeoPositionAddress* CreateGeoPositionAddress(JNIEnv *jenv, jobject jobj);
+    static jclass jAddressClass;
+    static jmethodID jGetAddressLineMethod;
+    static jmethodID jGetAdminAreaMethod;
+    static jmethodID jGetCountryNameMethod;
+    static jmethodID jGetFeatureNameMethod;
+    static jmethodID jGetLocalityMethod;
+    static jmethodID jGetPostalCodeMethod;
+    static jmethodID jGetPremisesMethod;
+    static jmethodID jGetSubAdminAreaMethod;
+    static jmethodID jGetSubLocalityMethod;
+    static jmethodID jGetSubThoroughfareMethod;
+    static jmethodID jGetThoroughfareMethod;
+};
+
 class AndroidGeckoEvent : public WrappedJavaObject
 {
 public:
     static void InitGeckoEventClass(JNIEnv *jEnv);
 
     AndroidGeckoEvent() { }
     AndroidGeckoEvent(int aType) {
         Init(aType);
@@ -415,16 +434,19 @@ public:
     int Action() { return mAction; }
     int Type() { return mType; }
     int64_t Time() { return mTime; }
     nsTArray<nsIntPoint> Points() { return mPoints; }
     nsTArray<int> PointIndicies() { return mPointIndicies; }
     nsTArray<float> Pressures() { return mPressures; }
     nsTArray<float> Orientations() { return mOrientations; }
     nsTArray<nsIntPoint> PointRadii() { return mPointRadii; }
+    double Alpha() { return mAlpha; }
+    double Beta() { return mBeta; }
+    double Gamma() { return mGamma; }
     double X() { return mX; }
     double Y() { return mY; }
     double Z() { return mZ; }
     double Distance() { return mDistance; }
     const nsIntRect& Rect() { return mRect; }
     nsAString& Characters() { return mCharacters; }
     nsAString& CharactersExtra() { return mCharactersExtra; }
     int KeyCode() { return mKeyCode; }
@@ -434,16 +456,17 @@ public:
     int Offset() { return mOffset; }
     int Count() { return mCount; }
     int PointerIndex() { return mPointerIndex; }
     int RangeType() { return mRangeType; }
     int RangeStyles() { return mRangeStyles; }
     int RangeForeColor() { return mRangeForeColor; }
     int RangeBackColor() { return mRangeBackColor; }
     nsGeoPosition* GeoPosition() { return mGeoPosition; }
+    nsGeoPositionAddress* GeoAddress() { return mGeoAddress; }
     double Bandwidth() { return mBandwidth; }
     bool CanBeMetered() { return mCanBeMetered; }
 
 protected:
     int mAction;
     int mType;
     int64_t mTime;
     nsTArray<nsIntPoint> mPoints;
@@ -452,21 +475,23 @@ protected:
     nsTArray<float> mOrientations;
     nsTArray<float> mPressures;
     nsIntRect mRect;
     int mFlags, mMetaState;
     int mKeyCode, mUnicodeChar;
     int mOffset, mCount;
     int mRangeType, mRangeStyles;
     int mRangeForeColor, mRangeBackColor;
+    double mAlpha, mBeta, mGamma;
     double mX, mY, mZ;
     double mDistance;
     int mPointerIndex;
     nsString mCharacters, mCharactersExtra;
     nsRefPtr<nsGeoPosition> mGeoPosition;
+    nsRefPtr<nsGeoPositionAddress> mGeoAddress;
     double mBandwidth;
     bool mCanBeMetered;
 
     void ReadIntArray(nsTArray<int> &aVals,
                       JNIEnv *jenv,
                       jfieldID field,
                       PRUint32 count);
     void ReadFloatArray(nsTArray<float> &aVals,
@@ -485,16 +510,19 @@ protected:
     static jfieldID jActionField;
     static jfieldID jTypeField;
     static jfieldID jTimeField;
     static jfieldID jPoints;
     static jfieldID jPointIndicies;
     static jfieldID jOrientations;
     static jfieldID jPressures;
     static jfieldID jPointRadii;
+    static jfieldID jAlphaField;
+    static jfieldID jBetaField;
+    static jfieldID jGammaField;
     static jfieldID jXField;
     static jfieldID jYField;
     static jfieldID jZField;
     static jfieldID jDistanceField;
     static jfieldID jRectField;
     static jfieldID jNativeWindowField;
 
     static jfieldID jCharactersField;
@@ -506,27 +534,28 @@ protected:
     static jfieldID jCountField;
     static jfieldID jPointerIndexField;
     static jfieldID jUnicodeCharField;
     static jfieldID jRangeTypeField;
     static jfieldID jRangeStylesField;
     static jfieldID jRangeForeColorField;
     static jfieldID jRangeBackColorField;
     static jfieldID jLocationField;
+    static jfieldID jAddressField;
 
     static jfieldID jBandwidthField;
     static jfieldID jCanBeMeteredField;
 
 public:
     enum {
         NATIVE_POKE = 0,
         KEY_EVENT = 1,
         MOTION_EVENT = 2,
-        SENSOR_EVENT = 3,
-        UNUSED1_EVENT = 4,
+        ORIENTATION_EVENT = 3,
+        ACCELERATION_EVENT = 4,
         LOCATION_EVENT = 5,
         IME_EVENT = 6,
         DRAW = 7,
         SIZE_CHANGED = 8,
         ACTIVITY_STOPPING = 9,
         ACTIVITY_PAUSING = 10,
         ACTIVITY_SHUTDOWN = 11,
         LOAD_URI = 12,
@@ -537,17 +566,16 @@ public:
         ACTIVITY_START = 17,
         BROADCAST = 19,
         VIEWPORT = 20,
         VISITED = 21,
         NETWORK_CHANGED = 22,
         PROXIMITY_EVENT = 23,
         ACTIVITY_RESUMING = 24,
         SCREENSHOT = 25,
-        SENSOR_ACCURACY = 26,
         dummy_java_enum_list_end
     };
 
     enum {
         IME_COMPOSITION_END = 0,
         IME_COMPOSITION_BEGIN = 1,
         IME_SET_TEXT = 2,
         IME_GET_TEXT = 3,
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -91,17 +91,17 @@ nsAppShell *nsAppShell::gAppShell = nsnu
 NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
 
 nsAppShell::nsAppShell()
     : mQueueLock("nsAppShell.mQueueLock"),
       mCondLock("nsAppShell.mCondLock"),
       mQueueCond(mCondLock, "nsAppShell.mQueueCond"),
       mNumDraws(0),
       mNumViewports(0),
-      mPendingSensorEvents(false)
+      mPendingOrientationEvents(false)
 {
     gAppShell = this;
 }
 
 nsAppShell::~nsAppShell()
 {
     gAppShell = nsnull;
 }
@@ -326,64 +326,42 @@ nsAppShell::ProcessNextNativeEvent(bool 
 
     EVLOG("nsAppShell: event %p %d [ndraws %d]", (void*)curEvent.get(), curEvent->Type(), mNumDraws);
 
     switch (curEvent->Type()) {
     case AndroidGeckoEvent::NATIVE_POKE:
         NativeEventCallback();
         break;
 
-    case AndroidGeckoEvent::SENSOR_ACCURACY:
-        if (curEvent->Flags() == 0)
-            gDeviceMotionSystem->NeedsCalibration();
+    case AndroidGeckoEvent::ACCELERATION_EVENT:
+        gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
+                                                 -curEvent->X(),
+                                                 curEvent->Y(),
+                                                 curEvent->Z());
         break;
 
-    case AndroidGeckoEvent::SENSOR_EVENT:
-        mPendingSensorEvents = false;
-        switch (curEvent->Flags()) {
-        case hal::SENSOR_ORIENTATION:
-            gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION,
-                                                     curEvent->X(),
-                                                     -curEvent->Y(),
-                                                     -curEvent->Z());
-            break;
-
-        case hal::SENSOR_ACCELERATION:
-            gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
-                                                     -curEvent->X(),
-                                                     curEvent->Y(),
-                                                     curEvent->Z());
-            break;
-
-        case hal::SENSOR_LINEAR_ACCELERATION:
-            gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_LINEAR_ACCELERATION,
-                                                     -curEvent->X(),
-                                                     curEvent->Y(),
-                                                     curEvent->Z());
-            break;
-
-        case hal::SENSOR_GYROSCOPE:
-            gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_GYROSCOPE,
-                                                     -curEvent->X(),
-                                                     curEvent->Y(),
-                                                     curEvent->Z());
-            break;
-
-        default:
-            __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### SENSOR_EVENT fired, but type wasn't known %d", curEvent->Flags());
-        }
-         break;
+    case AndroidGeckoEvent::ORIENTATION_EVENT:
+        gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION,
+                                                 -curEvent->Alpha(),
+                                                 curEvent->Beta(),
+                                                 curEvent->Gamma());
+        mPendingOrientationEvents = false;
+        break;
 
     case AndroidGeckoEvent::LOCATION_EVENT: {
         if (!gLocationCallback)
             break;
 
         nsGeoPosition* p = curEvent->GeoPosition();
-        if (p)
+        nsGeoPositionAddress* a = curEvent->GeoAddress();
+
+        if (p) {
+            p->SetAddress(a);
             gLocationCallback->Update(curEvent->GeoPosition());
+        }
         else
             NS_WARNING("Received location event without geoposition!");
         break;
     }
 
     case AndroidGeckoEvent::PROXIMITY_EVENT: {
         InfallibleTArray<float> values;
         values.AppendElement(curEvent->Distance());
@@ -619,20 +597,20 @@ nsAppShell::PostEvent(AndroidGeckoEvent 
             AndroidGeckoEvent *event;
             for (int i = mEventQueue.Length()-1; i >=1; i--) {
                 event = mEventQueue[i];
                 if (event->Type() == AndroidGeckoEvent::SURFACE_CREATED) {
                     mEventQueue.RemoveElementAt(i);
                     delete event;
                 }
             }
-        } else if (ae->Type() == AndroidGeckoEvent::SENSOR_EVENT) {
-            if (!mPendingSensorEvents)
-                mEventQueue.AppendElement(ae);
-            mPendingSensorEvents = true;
+        } else if (ae->Type() == AndroidGeckoEvent::ORIENTATION_EVENT) {
+            if (!mPendingOrientationEvents)
+                 mEventQueue.AppendElement(ae);
+            mPendingOrientationEvents = true;
         } else {
             mEventQueue.AppendElement(ae);
         }
 
         if (ae->Type() == AndroidGeckoEvent::DRAW) {
             mNumDraws++;
             mLastDrawEvent = ae;
         } else if (ae->Type() == AndroidGeckoEvent::VIEWPORT) {
--- a/widget/android/nsAppShell.h
+++ b/widget/android/nsAppShell.h
@@ -105,13 +105,13 @@ protected:
     mozilla::AndroidGeckoEvent *mLastDrawEvent;
     nsTArray<mozilla::AndroidGeckoEvent *> mEventQueue;
     nsInterfaceHashtable<nsStringHashKey, nsIObserver> mObserversHash;
 
     mozilla::AndroidGeckoEvent *PopNextEvent();
     mozilla::AndroidGeckoEvent *PeekNextEvent();
 
     nsCOMPtr<nsIAndroidBrowserApp> mBrowserApp;
-    bool mPendingSensorEvents;
+    bool mPendingOrientationEvents;
 };
 
 #endif // nsAppShell_h__
 
--- a/xpcom/system/nsIDeviceMotion.idl
+++ b/xpcom/system/nsIDeviceMotion.idl
@@ -38,31 +38,28 @@
 
 interface nsIDOMWindow;
 
 [scriptable, uuid(1B406E32-CF42-471E-A470-6FD600BF4C7B)]
 interface nsIDeviceMotionData : nsISupports
 {
   const unsigned long TYPE_ACCELERATION = 0;
   const unsigned long TYPE_ORIENTATION = 1;
-  const unsigned long TYPE_LINEAR_ACCELERATION = 2;
-  const unsigned long TYPE_GYROSCOPE = 3;
 
   readonly attribute unsigned long type;
 
   readonly attribute double x;
   readonly attribute double y;
   readonly attribute double z;
 };
 
-[scriptable, uuid(D29EA788-CCB6-4875-88E0-32A34BB71CBB)]
+[scriptable, uuid(f01774a2-3b7e-4630-954b-196dc178221f)]
 interface nsIDeviceMotionListener : nsISupports
 {
   void onMotionChange(in nsIDeviceMotionData aMotionData);
-  void needsCalibration();
 };
 
 [scriptable, uuid(B6E5C463-AAA6-44E2-BD07-7A7DC6192E68)]
 interface nsIDeviceMotion : nsISupports
 {
   void addListener(in nsIDeviceMotionListener aListener);
   void removeListener(in nsIDeviceMotionListener aListener);
 
@@ -71,15 +68,14 @@ interface nsIDeviceMotion : nsISupports
   [noscript] void addWindowListener(in nsIDOMWindow aWindow);
   [noscript] void removeWindowListener(in nsIDOMWindow aWindow);
 
 };
 
 /* for use by IPC system to notify non-chrome processes of 
  * device motion events
  */
-[uuid(C12C0157-DCFF-41B5-83F3-89179BF6CA4E)]
+[uuid(d3a56f08-b7b1-46bb-9dc1-fc3665a3631a)]
 interface nsIDeviceMotionUpdate : nsIDeviceMotion
 {
   /* must be called on the main thread or else */
   void deviceMotionChanged(in unsigned long type, in double x, in double y, in double z);
-  void needsCalibration();
 };