Back out bug 735330, bug 737462, bug 734854 because they broke XUL Fennec
authorMatt Brubeck <mbrubeck@mozilla.com>
Tue, 20 Mar 2012 16:59:24 -0700
changeset 89889 4c0b0a3c272f2a573ed8d466496824d1a2bce616
parent 89888 1fa638669fd98e72ebda5424b22b7c1b2958f40f
child 89890 c3d27335a1f22050946672ac8e9df673a6b8b0c5
push id7363
push usermbrubeck@mozilla.com
push dateWed, 21 Mar 2012 00:00:38 +0000
treeherdermozilla-inbound@4c0b0a3c272f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs735330, 737462, 734854
milestone14.0a1
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
Back out bug 735330, bug 737462, bug 734854 because they broke XUL Fennec
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/system/Makefile.in
dom/system/android/Makefile.in
dom/system/android/nsDeviceMotionSystem.cpp
dom/system/android/nsDeviceMotionSystem.h
dom/system/cocoa/Makefile.in
dom/system/cocoa/nsDeviceMotionSystem.h
dom/system/cocoa/nsDeviceMotionSystem.mm
dom/system/cocoa/nsHapticFeedback.cpp
dom/system/cocoa/nsHapticFeedback.h
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/unix/nsDeviceMotionSystem.h
dom/system/unix/nsQTMDeviceMotionSystem.cpp
dom/system/unix/nsQTMDeviceMotionSystem.h
dom/system/windows/Makefile.in
dom/system/windows/nsDeviceMotionSystem.cpp
dom/system/windows/nsDeviceMotionSystem.h
hal/Hal.cpp
hal/HalSensor.h
hal/Makefile.in
hal/android/AndroidSensor.cpp
hal/cocoa/CocoaSensor.mm
hal/cocoa/smslib.h
hal/cocoa/smslib.mm
hal/gonk/GonkSensor.cpp
hal/sandbox/PHal.ipdl
layout/build/nsLayoutModule.cpp
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoEvent.java
mobile/android/base/GeckoHalDefines.java
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJavaWrappers.cpp
widget/android/AndroidJavaWrappers.h
widget/android/nsAppShell.cpp
xpcom/system/nsIDeviceMotion.idl
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -91,16 +91,18 @@
 #include "nsIGeolocationProvider.h"
 #include "mozilla/dom/PMemoryReportRequestChild.h"
 
 #ifdef MOZ_PERMISSIONS
 #include "nsPermission.h"
 #include "nsPermissionManager.h"
 #endif
 
+#include "nsDeviceMotion.h"
+
 #if defined(MOZ_WIDGET_ANDROID)
 #include "APKOpen.h"
 #endif
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #endif
@@ -735,16 +737,38 @@ ContentChild::RecvAddPermission(const IP
                                  nsPermissionManager::eNotify,
                                  nsPermissionManager::eNoDBOperation);
 #endif
 
   return true;
 }
 
 bool
+ContentChild::RecvDeviceMotionChanged(const long int& type,
+                                      const double& x, const double& y,
+                                      const double& z)
+{
+    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
@@ -153,16 +153,22 @@ public:
     virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
 
     virtual bool RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON);
 
     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
@@ -91,16 +91,17 @@
 #include "nsExceptionHandler.h"
 #endif
 
 #include "mozilla/dom/ExternalHelperAppParent.h"
 #include "mozilla/dom/StorageParent.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
+#include "nsDeviceMotion.h"
 #include "mozilla/Util.h"
 
 #include "nsIMemoryReporter.h"
 #include "nsMemoryReporterManager.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 
 #ifdef ANDROID
 #include "gfxAndroidPlatform.h"
@@ -331,16 +332,17 @@ ContentParent::ActorDestroy(ActorDestroy
     // remove the global remote preferences observers
     nsCOMPtr<nsIPrefBranch> prefs 
             (do_GetService(NS_PREFSERVICE_CONTRACTID));
     if (prefs) { 
         prefs->RemoveObserver("", this);
     }
 
     RecvRemoveGeolocationListener();
+    RecvRemoveDeviceMotionListener();
 
     nsCOMPtr<nsIThreadInternal>
         threadInt(do_QueryInterface(NS_GetCurrentThread()));
     if (threadInt)
         threadInt->RemoveObserver(this);
     if (mRunToCompletionDepth)
         mRunToCompletionDepth = 0;
 
@@ -678,20 +680,21 @@ ContentParent::RecvGetShowPasswordSettin
 #ifdef MOZ_WIDGET_ANDROID
     NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available");
     if (AndroidBridge::Bridge() != nsnull)
         *showPassword = AndroidBridge::Bridge()->GetShowPasswordSetting();
 #endif
     return true;
 }
 
-NS_IMPL_THREADSAFE_ISUPPORTS3(ContentParent,
+NS_IMPL_THREADSAFE_ISUPPORTS4(ContentParent,
                               nsIObserver,
                               nsIThreadObserver,
-                              nsIDOMGeoPositionCallback)
+                              nsIDOMGeoPositionCallback,
+                              nsIDeviceMotionListener)
 
 NS_IMETHODIMP
 ContentParent::Observe(nsISupports* aSubject,
                        const char* aTopic,
                        const PRUnichar* aData)
 {
     if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
         Close();
@@ -1208,16 +1211,36 @@ ContentParent::RecvRemoveGeolocationList
       return true;
     }
     geo->ClearWatch(mGeolocationWatchID);
     mGeolocationWatchID = -1;
   }
   return true;
 }
 
+bool
+ContentParent::RecvAddDeviceMotionListener()
+{
+    nsCOMPtr<nsIDeviceMotion> dm = 
+        do_GetService(NS_DEVICE_MOTION_CONTRACTID);
+    if (dm)
+        dm->AddListener(this);
+    return true;
+}
+
+bool
+ContentParent::RecvRemoveDeviceMotionListener()
+{
+    nsCOMPtr<nsIDeviceMotion> dm = 
+        do_GetService(NS_DEVICE_MOTION_CONTRACTID);
+    if (dm)
+        dm->RemoveListener(this);
+    return true;
+}
+
 NS_IMETHODIMP
 ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
 {
   unused << SendGeolocationUpdate(GeoPosition(postion));
   return NS_OK;
 }
 
 bool
@@ -1250,10 +1273,30 @@ ContentParent::RecvScriptError(const nsS
                           aLineNumber, aColNumber, aFlags, aCategory.get());
   if (NS_FAILED(rv))
     return true;
 
   svc->LogMessage(msg);
   return true;
 }
 
+NS_IMETHODIMP
+ContentParent::OnMotionChange(nsIDeviceMotionData *aDeviceData) {
+    PRUint32 type;
+    double x, y, z;
+    aDeviceData->GetType(&type);
+    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/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -46,16 +46,17 @@
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
 #include "nsNetUtil.h"
 #include "nsIPrefService.h"
 #include "nsIPermissionManager.h"
 #include "nsIDOMGeoPositionCallback.h"
+#include "nsIDeviceMotion.h"
 #include "nsIMemoryReporter.h"
 #include "nsCOMArray.h"
 
 class nsFrameMessageManager;
 namespace mozilla {
 
 namespace ipc {
 class TestShellParent;
@@ -65,29 +66,31 @@ namespace dom {
 
 class TabParent;
 class PStorageParent;
 
 class ContentParent : public PContentParent
                     , public nsIObserver
                     , public nsIThreadObserver
                     , public nsIDOMGeoPositionCallback
+                    , public nsIDeviceMotionListener
 {
 private:
     typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
     typedef mozilla::ipc::TestShellParent TestShellParent;
 
 public:
     static ContentParent* GetNewOrUsed();
     static void GetAll(nsTArray<ContentParent*>& aArray);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
     NS_DECL_NSITHREADOBSERVER
     NS_DECL_NSIDOMGEOPOSITIONCALLBACK
+    NS_DECL_NSIDEVICEMOTIONLISTENER
 
     TabParent* CreateTab(PRUint32 aChromeFlags);
 
     TestShellParent* CreateTestShell();
     bool DestroyTestShell(TestShellParent* aTestShell);
     TestShellParent* GetTestShellSingleton();
 
     void ReportChildAlreadyBlocked();
@@ -210,16 +213,18 @@ private:
     virtual bool RecvLoadURIExternal(const IPC::URI& uri);
 
     virtual bool RecvSyncMessage(const nsString& aMsg, const nsString& aJSON,
                                  InfallibleTArray<nsString>* aRetvals);
     virtual bool RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON);
 
     virtual bool RecvAddGeolocationListener();
     virtual bool RecvRemoveGeolocationListener();
+    virtual bool RecvAddDeviceMotionListener();
+    virtual bool RecvRemoveDeviceMotionListener();
 
     virtual bool RecvConsoleMessage(const nsString& aMessage);
     virtual bool RecvScriptError(const nsString& aMessage,
                                  const nsString& aSourceName,
                                  const nsString& aSourceLine,
                                  const PRUint32& aLineNumber,
                                  const PRUint32& aColNumber,
                                  const PRUint32& aFlags,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -128,16 +128,19 @@ 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();
     
     /**
@@ -192,16 +195,18 @@ parent:
                           nsString name);
 
     PExternalHelperApp(URI uri, nsCString aMimeContentType,
                        nsCString aContentDisposition, bool aForceSave,
                        PRInt64 aContentLength, URI aReferrer);
     
     AddGeolocationListener();
     RemoveGeolocationListener();
+    AddDeviceMotionListener();
+    RemoveDeviceMotionListener();
 
     ConsoleMessage(nsString message);
     ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                 PRUint32 lineNumber, PRUint32 colNumber, PRUint32 flags,
                 nsCString category); 
 
     // nsIPermissionManager messages
     sync ReadPermissions() returns (Permission[] permissions);
--- a/dom/system/Makefile.in
+++ b/dom/system/Makefile.in
@@ -48,16 +48,20 @@ LIBXUL_LIBRARY  = 1
 ifneq (,$(filter qt gtk2,$(MOZ_WIDGET_TOOLKIT)))
 DIRS = unix
 endif
 
 ifneq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT)))
 DIRS = windows
 endif
 
+ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
+DIRS = cocoa
+endif
+
 ifneq (,$(filter android,$(MOZ_WIDGET_TOOLKIT)))
 DIRS = android
 endif
 
 ifdef MOZ_B2G_RIL
 DIRS += gonk
 endif
 
@@ -87,11 +91,11 @@ EXPORTS     = \
 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)/ipc/chromium/chromium-config.mk
+
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/system/android/Makefile.in
+++ b/dom/system/android/Makefile.in
@@ -48,16 +48,17 @@ LIBRARY_NAME    = domsystemandroid_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 CPPSRCS     = \
+        nsDeviceMotionSystem.cpp \
         AndroidLocationProvider.cpp \
         nsHapticFeedback.cpp \
         $(NULL)
 
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/src/geolocation \
                      -I$(topsrcdir)/content/events/src
                      $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/dom/system/android/nsDeviceMotionSystem.cpp
@@ -0,0 +1,73 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; 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.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Wu <mwu@mozilla.com>
+ *
+ * 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 "mozilla/dom/ContentChild.h"
+#include "nsDeviceMotionSystem.h"
+
+#include "AndroidBridge.h"
+#include "nsXULAppAPI.h"
+
+using namespace mozilla;
+
+extern nsDeviceMotionSystem *gDeviceMotionSystem;
+
+nsDeviceMotionSystem::nsDeviceMotionSystem()
+{
+    gDeviceMotionSystem = this;
+}
+
+nsDeviceMotionSystem::~nsDeviceMotionSystem()
+{
+}
+
+void nsDeviceMotionSystem::Startup()
+{
+    if (XRE_GetProcessType() == GeckoProcessType_Default)
+        AndroidBridge::Bridge()->EnableDeviceMotion(true);
+    else
+        mozilla::dom::ContentChild::GetSingleton()->
+            SendAddDeviceMotionListener();
+}
+
+void nsDeviceMotionSystem::Shutdown()
+{
+    if (XRE_GetProcessType() == GeckoProcessType_Default)
+        AndroidBridge::Bridge()->EnableDeviceMotion(false);
+    else
+        mozilla::dom::ContentChild::GetSingleton()->
+            SendRemoveDeviceMotionListener();
+}
new file mode 100644
--- /dev/null
+++ b/dom/system/android/nsDeviceMotionSystem.h
@@ -0,0 +1,54 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Wu <mwu@mozilla.com>
+ *
+ * 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 ***** */
+
+#ifndef nsDeviceMotionSystem_h
+#define nsDeviceMotionSystem_h
+
+#include "nsDeviceMotion.h"
+
+class nsDeviceMotionSystem : public nsDeviceMotion
+{
+public:
+  nsDeviceMotionSystem();
+  virtual ~nsDeviceMotionSystem();
+
+private:
+  virtual void Startup();
+  virtual void Shutdown();
+};
+
+#endif /* nsDeviceMotionSystem_h */
+
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/Makefile.in
@@ -0,0 +1,62 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org build system.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Mike Kristoffersen <mikek@mikek.dk>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH       = ../../..
+topsrcdir   = @top_srcdir@
+srcdir      = @srcdir@
+VPATH       = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE      = dom
+LIBRARY_NAME    = 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
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/nsDeviceMotionSystem.h
@@ -0,0 +1,59 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Doug Turner <dougt@dougt.org>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * 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 ***** */
+
+#ifndef nsDeviceMotionSystem_h
+#define nsDeviceMotionSystem_h
+
+#include <IOKit/IOKitLib.h>
+#include <mach/mach_port.h>
+
+#include "nsDeviceMotion.h"
+
+class nsDeviceMotionSystem : public nsDeviceMotion
+{
+ public:
+  nsDeviceMotionSystem();
+  ~nsDeviceMotionSystem();
+
+  void Startup();
+  void Shutdown();
+
+  io_connect_t mSmsConnection;
+  nsCOMPtr<nsITimer> mUpdateTimer;
+  static void UpdateHandler(nsITimer *aTimer, void *aClosure);
+};
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/nsDeviceMotionSystem.mm
@@ -0,0 +1,96 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Doug Turner <dougt@dougt.org>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * 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 ***** */
+
+#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
+
+nsDeviceMotionSystem::nsDeviceMotionSystem()
+{
+}
+
+nsDeviceMotionSystem::~nsDeviceMotionSystem()
+{
+}
+
+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);
+
+  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
+			    accel.x * MEAN_GRAVITY,
+			    accel.y * MEAN_GRAVITY,
+			    accel.z * MEAN_GRAVITY);
+}
+
+void nsDeviceMotionSystem::Startup()
+{
+  smsStartup(nil, nil);
+  smsLoadCalibration();
+
+  mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
+  if (mUpdateTimer)
+    mUpdateTimer->InitWithFuncCallback(UpdateHandler,
+                                       this,
+                                       DEFAULT_SENSOR_POLL,
+                                       nsITimer::TYPE_REPEATING_SLACK);
+}
+
+void nsDeviceMotionSystem::Shutdown()
+{
+  if (mUpdateTimer) {
+    mUpdateTimer->Cancel();
+    mUpdateTimer = nsnull;
+  }
+
+  smsShutdown();
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/nsHapticFeedback.cpp
@@ -0,0 +1,47 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; 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 code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Lassey <blassey@mozilla.com>
+ *
+ * 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 "nsHapticFeedback.h"
+
+NS_IMPL_ISUPPORTS1(nsHapticFeedback, nsIHapticFeedback)
+
+NS_IMETHODIMP
+nsHapticFeedback::PerformSimpleAction(PRInt32 aType)
+{
+    // Todo
+    return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/dom/system/cocoa/nsHapticFeedback.h
@@ -0,0 +1,45 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; 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 code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brad Lassey <blassey@mozilla.com>
+ *
+ * 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 "nsIHapticFeedback.h"
+
+class nsHapticFeedback : public nsIHapticFeedback
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIHAPTICFEEDBACK
+};
rename from hal/cocoa/smslib.h
rename to dom/system/cocoa/smslib.h
rename from hal/cocoa/smslib.mm
rename to dom/system/cocoa/smslib.mm
--- a/dom/system/nsDeviceMotion.cpp
+++ b/dom/system/nsDeviceMotion.cpp
@@ -29,34 +29,31 @@
  * 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 "mozilla/Hal.h"
-#include "mozilla/HalSensor.h"
-
 #include "nsDeviceMotion.h"
 
 #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 "nsIServiceManager.h"
 #include "nsIPrefService.h"
 
-using namespace mozilla;
-using namespace hal;
+using mozilla::TimeStamp;
+using mozilla::TimeDuration;
 
 // also see sDefaultSensorHint in mobile/android/base/GeckoAppShell.java
 #define DEFAULT_SENSOR_POLL 100
 
 static const nsTArray<nsIDOMWindow*>::index_type NoIndex =
     nsTArray<nsIDOMWindow*>::NoIndex;
 
 class nsDeviceMotionData : public nsIDeviceMotionData
@@ -114,40 +111,34 @@ NS_IMETHODIMP nsDeviceMotionData::GetY(d
 
 NS_IMETHODIMP nsDeviceMotionData::GetZ(double *aZ)
 {
   NS_ENSURE_ARG_POINTER(aZ);
   *aZ = mZ;
   return NS_OK;
 }
 
-NS_IMPL_ISUPPORTS1(nsDeviceMotion, nsIDeviceMotion)
+NS_IMPL_ISUPPORTS2(nsDeviceMotion, nsIDeviceMotion, nsIDeviceMotionUpdate)
 
 nsDeviceMotion::nsDeviceMotion()
 : mStarted(false),
   mEnabled(true)
 {
-  mLastDOMMotionEventTime = TimeStamp::Now();
-  mLastAccuracy = SENSOR_ACCURACY_UNKNOWN;
-
   nsCOMPtr<nsIPrefBranch> prefSrv = do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (prefSrv) {
     bool bvalue;
     nsresult rv = prefSrv->GetBoolPref("device.motion.enabled", &bvalue);
     if (NS_SUCCEEDED(rv) && bvalue == false)
       mEnabled = false;
   }
   mLastDOMMotionEventTime = TimeStamp::Now();
 }
 
 nsDeviceMotion::~nsDeviceMotion()
 {
-  if (mStarted)
-    Shutdown();
-
   if (mTimeoutTimer)
     mTimeoutTimer->Cancel();
 }
 
 void
 nsDeviceMotion::StartDisconnectTimer()
 {
   if (mTimeoutTimer)
@@ -223,34 +214,21 @@ NS_IMETHODIMP nsDeviceMotion::RemoveWind
   if (mWindowListeners.IndexOf(aWindow) == NoIndex)
     return NS_OK;
 
   mWindowListeners.RemoveElement(aWindow);
   StartDisconnectTimer();
   return NS_OK;
 }
 
-void 
-nsDeviceMotion::Notify(const mozilla::hal::SensorData& aSensorData)
+NS_IMETHODIMP
+nsDeviceMotion::DeviceMotionChanged(PRUint32 type, double x, double y, double z)
 {
   if (!mEnabled)
-    return;
-
-  PRUint32 type = aSensorData.sensor();
-
-  double x = aSensorData.values()[0];
-  double y = aSensorData.values()[1];
-  double z = aSensorData.values()[2];
-
-  SensorAccuracyType accuracy = aSensorData.accuracy();
-
-  if (accuracy <= SENSOR_ACCURACY_LOW && mLastAccuracy >= SENSOR_ACCURACY_MED) {
-    FireNeedsCalibration();
-  }
-  mLastAccuracy = accuracy;
+    return NS_ERROR_NOT_INITIALIZED;
 
   nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
   for (PRUint32 i = listeners.Count(); i > 0 ; ) {
     --i;
     nsRefPtr<nsDeviceMotionData> a = new nsDeviceMotionData(type, x, y, z);
     listeners[i]->OnMotionChange(a);
   }
 
@@ -272,29 +250,30 @@ nsDeviceMotion::Notify(const mozilla::ha
 
     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)
+        type == nsIDeviceMotionData::TYPE_GYROSCOPE )
         FireDOMMotionEvent(domdoc, target, type, x, y, z);
       else if (type == nsIDeviceMotionData::TYPE_ORIENTATION)
         FireDOMOrientationEvent(domdoc, target, x, y, z);
     }
   }
+  return NS_OK;
 }
 
-void
-nsDeviceMotion::FireNeedsCalibration()
+NS_IMETHODIMP
+nsDeviceMotion::NeedsCalibration()
 {
   if (!mEnabled)
-    return;
+    return NS_ERROR_NOT_INITIALIZED;
 
   nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
   for (PRUint32 i = listeners.Count(); i > 0 ; ) {
     --i;
     listeners[i]->NeedsCalibration();
   }
 
   nsCOMArray<nsIDOMWindow> windowListeners;
@@ -316,16 +295,18 @@ nsDeviceMotion::FireNeedsCalibration()
     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));
@@ -423,28 +404,11 @@ nsDeviceMotion::FireDOMMotionEvent(nsIDO
   
   bool defaultActionEnabled = true;
   target->DispatchEvent(event, &defaultActionEnabled);
 
   mLastRotationRate = nsnull;
   mLastAccelerationIncluduingGravity = nsnull;
   mLastAcceleration = nsnull;
   mLastDOMMotionEventTime = TimeStamp::Now();
+
 }
 
-void nsDeviceMotion::Startup()
-{
-  // Bug 734855 - we probably can make this finer grain
-  // based on the DOM APIs that are being invoked.
-  RegisterSensorObserver(SENSOR_ACCELERATION, this);
-  RegisterSensorObserver(SENSOR_ORIENTATION, this);
-  RegisterSensorObserver(SENSOR_LINEAR_ACCELERATION, this);
-  RegisterSensorObserver(SENSOR_GYROSCOPE, this);
-}
-
-void nsDeviceMotion::Shutdown()
-{
-  UnregisterSensorObserver(SENSOR_ACCELERATION, this);
-  UnregisterSensorObserver(SENSOR_ORIENTATION, this);
-  UnregisterSensorObserver(SENSOR_LINEAR_ACCELERATION, this);
-  UnregisterSensorObserver(SENSOR_GYROSCOPE, this);
-}
-
--- a/dom/system/nsDeviceMotion.h
+++ b/dom/system/nsDeviceMotion.h
@@ -42,52 +42,48 @@
 #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"
-#include "mozilla/HalSensor.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;
 
-class nsDeviceMotion : public nsIDeviceMotion, public mozilla::hal::ISensorObserver
+class nsDeviceMotion : public nsIDeviceMotionUpdate
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDEVICEMOTION
+  NS_DECL_NSIDEVICEMOTIONUPDATE
 
   nsDeviceMotion();
 
   virtual ~nsDeviceMotion();
 
-  void Notify(const mozilla::hal::SensorData& aSensorData);
-
 private:
   nsCOMArray<nsIDeviceMotionListener> mListeners;
   nsTArray<nsIDOMWindow*> mWindowListeners;
 
   void StartDisconnectTimer();
 
   bool mStarted;
 
   nsCOMPtr<nsITimer> mTimeoutTimer;
   static void TimeoutHandler(nsITimer *aTimer, void *aClosure);
 
  protected:
-  void FireNeedsCalibration();
 
   void FireNeedsCalibration(nsIDOMDocument *domdoc,
 			    nsIDOMEventTarget *target);
 
   void FireDOMOrientationEvent(class nsIDOMDocument *domDoc, 
                                class nsIDOMEventTarget *target,
                                double alpha,
                                double beta,
@@ -95,20 +91,20 @@ private:
 
   void FireDOMMotionEvent(class nsIDOMDocument *domDoc, 
                           class nsIDOMEventTarget *target,
                           PRUint32 type,
                           double x,
                           double y,
                           double z);
 
-  void Startup();
-  void Shutdown();
+  virtual void Startup()  = 0;
+  virtual void Shutdown() = 0;
 
   bool mEnabled;
   mozilla::TimeStamp mLastDOMMotionEventTime;
-  mozilla::hal::SensorAccuracyType mLastAccuracy;
   nsRefPtr<nsDOMDeviceAcceleration> mLastAcceleration;
   nsRefPtr<nsDOMDeviceAcceleration> mLastAccelerationIncluduingGravity;
   nsRefPtr<nsDOMDeviceRotationRate> mLastRotationRate;
+
 };
 
 #endif
--- a/dom/system/unix/Makefile.in
+++ b/dom/system/unix/Makefile.in
@@ -48,31 +48,41 @@ LIBRARY_NAME    = domsystemunix_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
 
+ifndef MOZ_ENABLE_QTMOBILITY
+CPPSRCS     = \
+        nsDeviceMotionSystem.cpp \
+        $(NULL)
+endif
+
 ifdef MOZ_MAEMO_LIBLOCATION
         CPPSRCS         += MaemoLocationProvider.cpp
         LOCAL_INCLUDES  += $(MOZ_PLATFORM_MAEMO_CFLAGS) \
                            -I$(topsrcdir)/dom/src/geolocation \
                            $(NULL)
 endif
 
 ifdef MOZ_PLATFORM_MAEMO
 CPPSRCS += nsHapticFeedback.cpp
 LOCAL_INCLUDES  += $(MOZ_DBUS_CFLAGS) \
                    $(NULL)
 ifdef MOZ_ENABLE_QTMOBILITY
-MOCSRCS         += moc_QTMLocationProvider.cpp
+MOCSRCS         += moc_QTMLocationProvider.cpp moc_nsQTMDeviceMotionSystem.cpp
 CPPSRCS         += $(MOCSRCS) \
                    QTMLocationProvider.cpp \
+                   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
new file mode 100644
--- /dev/null
+++ b/dom/system/unix/nsDeviceMotionSystem.cpp
@@ -0,0 +1,253 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Ventnor <m.ventnor@gmail.com>
+ *
+ * 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 <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;
+
+static const AccelerometerData gAccelerometers[] = {
+  // MacBook
+  {"/sys/devices/platform/applesmc.768/position",
+   "/sys/devices/platform/applesmc.768/calibrate",
+   eAppleSensor},
+  // Thinkpad
+  {"/sys/devices/platform/hdaps/position",
+   "/sys/devices/platform/hdaps/calibrate",
+   eIBMSensor},
+  // Maemo Fremantle
+  {"/sys/class/i2c-adapter/i2c-3/3-001d/coord",
+   NULL,
+   eMaemoSensor},
+  // HP Pavilion dv7
+  {"/sys/devices/platform/lis3lv02d/position",
+   "/sys/devices/platform/lis3lv02d/calibrate",
+   eHPdv7Sensor},
+};
+
+nsDeviceMotionSystem::nsDeviceMotionSystem() :
+  mPositionFile(NULL),
+  mCalibrateFile(NULL),
+  mType(eNoSensor)
+{
+}
+
+nsDeviceMotionSystem::~nsDeviceMotionSystem()
+{
+}
+
+void
+nsDeviceMotionSystem::UpdateHandler(nsITimer *aTimer, void *aClosure)
+{
+  nsDeviceMotionSystem *self = reinterpret_cast<nsDeviceMotionSystem *>(aClosure);
+  if (!self) {
+    NS_ERROR("no self");
+    return;
+  }
+
+  float xf, yf, zf;
+
+  switch (self->mType) {
+    case eAppleSensor:
+    {
+      int x, y, z, calibrate_x, calibrate_y;
+      fflush(self->mCalibrateFile);
+      rewind(self->mCalibrateFile);
+
+      fflush(self->mPositionFile);
+      rewind(self->mPositionFile);
+
+      if (fscanf(self->mCalibrateFile, "(%d, %d)", &calibrate_x, &calibrate_y) <= 0)
+        return;
+
+      if (fscanf(self->mPositionFile, "(%d, %d, %d)", &x, &y, &z) <= 0)
+        return;
+
+      // In applesmc:
+      // - the x calibration value is negated
+      // - a negative z actually means a correct-way-up computer
+      // - dividing by 255 gives us the intended value of -1 to 1
+      xf = ((float)(x + calibrate_x)) / 255.0;
+      yf = ((float)(y - calibrate_y)) / 255.0;
+      zf = ((float)z) / -255.0;
+      break;
+    }
+    case eIBMSensor:
+    {
+      int x, y, calibrate_x, calibrate_y;
+      fflush(self->mCalibrateFile);
+      rewind(self->mCalibrateFile);
+
+      fflush(self->mPositionFile);
+      rewind(self->mPositionFile);
+
+      if (fscanf(self->mCalibrateFile, "(%d, %d)", &calibrate_x, &calibrate_y) <= 0)
+        return;
+
+      if (fscanf(self->mPositionFile, "(%d, %d)", &x, &y) <= 0)
+        return;
+
+      xf = ((float)(x - calibrate_x)) / 180.0;
+      yf = ((float)(y - calibrate_y)) / 180.0;
+      zf = 1.0f;
+      break;
+    }
+    case eMaemoSensor:
+    {
+      int x, y, z;
+      fflush(self->mPositionFile);
+      rewind(self->mPositionFile);
+
+      if (fscanf(self->mPositionFile, "%d %d %d", &x, &y, &z) <= 0)
+        return;
+
+      xf = ((float)x) / -1000.0;
+      yf = ((float)y) / -1000.0;
+      zf = ((float)z) / -1000.0;
+      break;
+    }
+    case eHPdv7Sensor:
+    {
+      int x, y, z, calibrate_x, calibrate_y, calibrate_z;
+      fflush(self->mCalibrateFile);
+      rewind(self->mCalibrateFile);
+
+      fflush(self->mPositionFile);
+      rewind(self->mPositionFile);
+
+      if (fscanf(self->mCalibrateFile, "(%d,%d,%d)", &calibrate_x, &calibrate_y, &calibrate_z) <= 0)
+        return;
+
+      if (fscanf(self->mPositionFile, "(%d,%d,%d)", &x, &y, &z) <= 0)
+        return;
+
+      // Example data:
+      //
+      // Calibration (-4,0,51)
+      // flat on the table (-5,-2,50)
+      // Tilted on its left side (-60,0,-4)
+      // Tilted on its right side (51,1,-1)
+      // upside down (-2,3,-60)
+      //
+      // So assuming the calibration data shows the acceleration
+      // (1G) measured with the notebook laying flat on the table
+      // it would mean that our best bet, is to ignore the z-axis
+      // calibration...  We are still way off, but it's hard to
+      // see how to get better data without doing calibration with
+      // user intervention (like: Turn your notbook slowly around
+      // so every edge and the top and bottom points up in turn)
+
+      xf = ((float)(x - calibrate_x)) / 60.0;
+      yf = ((float)(y - calibrate_y)) / 60.0;
+      zf = ((float)(z)) / 60.0;
+      break;
+    }
+
+    case eNoSensor:
+    default:
+      return;
+  }
+
+  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, xf, yf, zf );
+}
+
+void nsDeviceMotionSystem::Startup()
+{
+  // Accelerometers in Linux are used by reading a file (yay UNIX!), which is
+  // in a slightly different location depending on the driver.
+  for (unsigned int i = 0; i < ArrayLength(gAccelerometers); i++) {
+    if (!(mPositionFile = fopen(gAccelerometers[i].mPosition, "r")))
+      continue;
+
+    mType = gAccelerometers[i].mToken;
+    if (gAccelerometers[i].mCalibrate) {
+      mCalibrateFile = fopen(gAccelerometers[i].mCalibrate, "r");
+      if (!mCalibrateFile) {
+        fclose(mPositionFile);
+        mPositionFile = nsnull;
+        return;
+      }
+    }
+
+    break;
+  }
+
+  if (mType == eNoSensor)
+    return;
+
+  mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
+  if (mUpdateTimer)
+    mUpdateTimer->InitWithFuncCallback(UpdateHandler,
+                                       this,
+                                       DEFAULT_SENSOR_POLL,
+                                       nsITimer::TYPE_REPEATING_SLACK);
+}
+
+void nsDeviceMotionSystem::Shutdown()
+{
+  if (mPositionFile) {
+    fclose(mPositionFile);
+    mPositionFile = nsnull;
+  }
+
+  // Fun fact: writing to the calibrate file causes the
+  // driver to re-calibrate the accelerometer
+  if (mCalibrateFile) {
+    fclose(mCalibrateFile);
+    mCalibrateFile = nsnull;
+  }
+
+  mType = eNoSensor;
+
+  if (mUpdateTimer) {
+    mUpdateTimer->Cancel();
+    mUpdateTimer = nsnull;
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/system/unix/nsDeviceMotionSystem.h
@@ -0,0 +1,71 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Ventnor <m.ventnor@gmail.com>
+ *
+ * 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 ***** */
+
+#ifndef nsDeviceMotionSystem_h
+#define nsDeviceMotionSystem_h
+
+#include <unistd.h>
+#include <stdio.h>
+#include "nsDeviceMotion.h"
+
+enum nsAccelerometerSystemDriver
+{
+  eNoSensor,
+  eAppleSensor,
+  eIBMSensor,
+  eMaemoSensor,
+  eHPdv7Sensor
+};
+
+class nsDeviceMotionSystem : public nsDeviceMotion
+{
+ public:
+  nsDeviceMotionSystem();
+  ~nsDeviceMotionSystem();
+
+  void Startup();
+  void Shutdown();
+
+  FILE* mPositionFile;
+  FILE* mCalibrateFile;
+  nsAccelerometerSystemDriver mType;
+
+  nsCOMPtr<nsITimer> mUpdateTimer;
+  static void UpdateHandler(nsITimer *aTimer, void *aClosure);
+};
+
+#endif
new file mode 100644
--- /dev/null
+++ b/dom/system/unix/nsQTMDeviceMotionSystem.cpp
@@ -0,0 +1,126 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; 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.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Oleg Romashin <romaxa@gmail.com>
+ *
+ * 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 "mozilla/dom/ContentChild.h"
+#include "nsQTMDeviceMotionSystem.h"
+#include <QObject>
+#include <QtSensors/QAccelerometer>
+#include <QtSensors/QRotationSensor>
+
+#include "nsXULAppAPI.h"
+
+using namespace mozilla;
+using namespace QtMobility;
+
+bool
+MozQAccelerometerSensorFilter::filter(QAccelerometerReading* reading)
+{
+    mSystem.DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
+                                -reading->x(),
+                                -reading->y(),
+                                -reading->z());
+    return true;
+}
+
+bool
+MozQRotationSensorFilter::filter(QRotationReading* reading)
+{
+    // QRotationReading class:
+    // - the rotation around z axis (alpha) is given as z in QRotationReading;
+    // - the rotation around x axis (beta) is given as x in QRotationReading;
+    // - the rotation around y axis (gamma) is given as y in QRotationReading;
+    // See: http://doc.qt.nokia.com/qtmobility-1.0/qrotationreading.html
+    mSystem.DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION,
+                                reading->z(),
+                                reading->x(),
+                                reading->y());
+    return true;
+}
+
+nsDeviceMotionSystem::nsDeviceMotionSystem()
+{
+    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+        mAccelerometer = new QAccelerometer();
+        mAccelerometerFilter = new MozQAccelerometerSensorFilter(*this);
+        mAccelerometer->addFilter(mAccelerometerFilter);
+        mRotation = new QRotationSensor();
+        mRotationFilter = new MozQRotationSensorFilter(*this);
+        mRotation->addFilter(mRotationFilter);
+    }
+}
+
+nsDeviceMotionSystem::~nsDeviceMotionSystem()
+{
+    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+        mAccelerometer->removeFilter(mAccelerometerFilter);
+        mAccelerometer->stop();
+        mRotation->removeFilter(mRotationFilter);
+        mRotation->stop();
+        delete mAccelerometer;
+        delete mAccelerometerFilter;
+        delete mRotation;
+        delete mRotationFilter;
+    }
+}
+
+void nsDeviceMotionSystem::Startup()
+{
+    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+        mAccelerometer->start();
+        if (!mAccelerometer->isActive()) {
+            NS_WARNING("AccelerometerSensor didn't start!");
+        }
+        mRotation->start();
+        if (!mRotation->isActive()) {
+            NS_WARNING("RotationSensor didn't start!");
+        }
+    }
+    else
+        mozilla::dom::ContentChild::GetSingleton()->
+            SendAddDeviceMotionListener();
+}
+
+void nsDeviceMotionSystem::Shutdown()
+{
+    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+        mAccelerometer->stop();
+        mRotation->stop();
+    }
+    else
+        mozilla::dom::ContentChild::GetSingleton()->
+            SendRemoveDeviceMotionListener();
+}
new file mode 100644
--- /dev/null
+++ b/dom/system/unix/nsQTMDeviceMotionSystem.h
@@ -0,0 +1,100 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Oleg Romashin <romaxa@gmail.com>
+ *
+ * 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 ***** */
+
+#ifndef nsDeviceMotionSystem_h
+#define nsDeviceMotionSystem_h
+
+#include <QObject>
+#include <QtSensors/QAccelerometer>
+#include <QtSensors/QRotationSensor>
+#include "nsDeviceMotion.h"
+
+using namespace QtMobility;
+
+
+class MozQAccelerometerSensorFilter;
+class MozQRotationSensorFilter;
+
+class nsDeviceMotionSystem : public nsDeviceMotion
+{
+public:
+  nsDeviceMotionSystem();
+  virtual ~nsDeviceMotionSystem();
+
+private:
+  virtual void Startup();
+  virtual void Shutdown();
+
+  QtMobility::QAccelerometer* mAccelerometer;
+  MozQAccelerometerSensorFilter* mAccelerometerFilter;
+  QtMobility::QRotationSensor* mRotation;
+  MozQRotationSensorFilter* mRotationFilter;
+};
+
+class MozQAccelerometerSensorFilter : public QObject, public QAccelerometerFilter
+{
+    Q_OBJECT
+
+public:
+    MozQAccelerometerSensorFilter(nsDeviceMotionSystem& aSystem) : mSystem(aSystem) {}
+
+    virtual ~MozQAccelerometerSensorFilter(){}
+
+    virtual bool filter(QAccelerometerReading* reading);
+
+private:
+    bool filter(QSensorReading *reading) { return filter(static_cast<QAccelerometerReading*>(reading)); }
+    nsDeviceMotionSystem& mSystem;
+};
+
+class MozQRotationSensorFilter : public QObject, public QRotationFilter
+{
+    Q_OBJECT
+
+public:
+    MozQRotationSensorFilter(nsDeviceMotionSystem& aSystem) : mSystem(aSystem) {}
+
+    virtual ~MozQRotationSensorFilter(){}
+
+    virtual bool filter(QRotationReading* reading);
+
+private:
+    bool filter(QSensorReading *reading) { return filter(static_cast<QRotationReading*>(reading)); }
+    nsDeviceMotionSystem& mSystem;
+};
+
+#endif /* nsDeviceMotionSystem_h */
+
--- a/dom/system/windows/Makefile.in
+++ b/dom/system/windows/Makefile.in
@@ -50,12 +50,13 @@ 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
new file mode 100644
--- /dev/null
+++ b/dom/system/windows/nsDeviceMotionSystem.cpp
@@ -0,0 +1,175 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Doug Turner <dougt@dougt.org>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jesper Kristensen <mail@jesperkristensen.dk>
+ *
+ * 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 "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
+  unsigned short xx; // avg. of 40ms
+  unsigned short yy; // avg. of 40ms
+  char temp; // raw value (could be deg celsius?)
+  unsigned short x0; // Used for "auto-center"
+  unsigned short y0; // Used for "auto-center"
+} ThinkPadAccelerometerData;
+
+typedef void (__stdcall *ShockproofGetAccelerometerData)(ThinkPadAccelerometerData*);
+
+ShockproofGetAccelerometerData gShockproofGetAccelerometerData = nsnull;
+
+class ThinkPadSensor : public Sensor
+{
+public:
+  ThinkPadSensor();
+  ~ThinkPadSensor();
+  bool Startup();
+  void Shutdown();
+  void GetValues(double *x, double *y, double *z);
+private:
+  HMODULE mLibrary;
+};
+
+ThinkPadSensor::ThinkPadSensor()
+{
+}
+
+ThinkPadSensor::~ThinkPadSensor()
+{
+}
+
+bool
+ThinkPadSensor::Startup()
+{
+  mLibrary = LoadLibraryW(L"sensor.dll");
+  if (!mLibrary)
+    return false;
+
+  gShockproofGetAccelerometerData = (ShockproofGetAccelerometerData)
+    GetProcAddress(mLibrary, "ShockproofGetAccelerometerData");
+  if (!gShockproofGetAccelerometerData) {
+    FreeLibrary(mLibrary);
+    mLibrary = nsnull;
+    return false;
+  }
+  return true;
+}
+
+void
+ThinkPadSensor::Shutdown()
+{
+  if (mLibrary == nsnull)
+    return;
+
+  FreeLibrary(mLibrary);
+  mLibrary = nsnull;
+  gShockproofGetAccelerometerData = nsnull;
+}
+
+void
+ThinkPadSensor::GetValues(double *x, double *y, double *z)
+{
+  ThinkPadAccelerometerData accelData;
+
+  gShockproofGetAccelerometerData(&accelData);
+
+  // accelData.x and accelData.y is the acceleration measured from the accelerometer.
+  // x and y is switched from what we use, and the accelerometer does not support z axis.
+  // Balance point (526, 528) and 90 degree tilt (144) determined experimentally.
+  *x = ((double)(accelData.y - 526)) / 144;
+  *y = ((double)(accelData.x - 528)) / 144;
+  *z = 1.0;
+}
+
+nsDeviceMotionSystem::nsDeviceMotionSystem(){}
+nsDeviceMotionSystem::~nsDeviceMotionSystem(){}
+
+void
+nsDeviceMotionSystem::UpdateHandler(nsITimer *aTimer, void *aClosure)
+{
+  nsDeviceMotionSystem *self = reinterpret_cast<nsDeviceMotionSystem *>(aClosure);
+  if (!self || !self->mSensor) {
+    NS_ERROR("no self or sensor");
+    return;
+  }
+  double x, y, z;
+  self->mSensor->GetValues(&x, &y, &z);
+  self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, x, y, z);
+}
+
+void nsDeviceMotionSystem::Startup()
+{
+  NS_ASSERTION(!mSensor, "mSensor should be null.  Startup called twice?");
+
+  bool started = false;
+
+  mSensor = new ThinkPadSensor();
+  if (mSensor)
+    started = mSensor->Startup();
+
+  if (!started) {
+    mSensor = nsnull;
+    return;
+  }
+
+  mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
+  if (mUpdateTimer)
+    mUpdateTimer->InitWithFuncCallback(UpdateHandler,
+                                       this,
+                                       DEFAULT_SENSOR_POLL,
+                                       nsITimer::TYPE_REPEATING_SLACK);
+}
+
+void nsDeviceMotionSystem::Shutdown()
+{
+  if (mUpdateTimer) {
+    mUpdateTimer->Cancel();
+    mUpdateTimer = nsnull;
+  }
+
+  if (mSensor)
+    mSensor->Shutdown();
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/system/windows/nsDeviceMotionSystem.h
@@ -0,0 +1,66 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Doug Turner <dougt@dougt.org>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * 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 ***** */
+
+#ifndef nsDeviceMotionSystem_h
+#define nsDeviceMotionSystem_h
+
+#include "nsDeviceMotion.h"
+#include "nsAutoPtr.h"
+
+class Sensor
+{
+ public:
+  virtual bool Startup() = 0;
+  virtual void Shutdown()  = 0;
+  virtual void GetValues(double *x, double *y, double *z) = 0;
+};
+
+class nsDeviceMotionSystem : public nsDeviceMotion
+{
+ public:
+  nsDeviceMotionSystem();
+  ~nsDeviceMotionSystem();
+
+  void Startup();
+  void Shutdown();
+
+  nsCOMPtr<nsITimer> mUpdateTimer;
+  static void UpdateHandler(nsITimer *aTimer, void *aClosure);
+
+  nsAutoPtr<Sensor> mSensor;
+};
+
+#endif
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -410,17 +410,17 @@ EnableSensorNotifications(SensorType aSe
 
 void
 DisableSensorNotifications(SensorType aSensor) {
   AssertMainThread();
   PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor));
 }
 
 typedef mozilla::ObserverList<SensorData> SensorObserverList;
-static SensorObserverList* gSensorObservers = NULL;
+static SensorObserverList *gSensorObservers = NULL;
 
 static SensorObserverList &
 GetSensorObservers(SensorType sensor_type) {
   MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
   
   if(gSensorObservers == NULL)
     gSensorObservers = new SensorObserverList[NUM_SENSOR_TYPE];
   return gSensorObservers[sensor_type];
@@ -442,18 +442,16 @@ void
 UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
   SensorObserverList &observers = GetSensorObservers(aSensor);
 
   AssertMainThread();
   
   observers.RemoveObserver(aObserver);
   if(observers.Length() == 0) {
     DisableSensorNotifications(aSensor);
-    delete [] gSensorObservers;
-    gSensorObservers = nsnull;
   }
 }
 
 void
 NotifySensorChange(const SensorData &aSensorData) {
   SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
 
   AssertMainThread();
--- a/hal/HalSensor.h
+++ b/hal/HalSensor.h
@@ -58,50 +58,28 @@ enum SensorType {
   SENSOR_GYROSCOPE,
   NUM_SENSOR_TYPE
 };
 
 class SensorData;
 
 typedef Observer<SensorData> ISensorObserver;
 
-/**
- * Enumeration of sensor accuracy types.
- */
-enum SensorAccuracyType {
-  SENSOR_ACCURACY_UNKNOWN = -1,
-  SENSOR_ACCURACY_UNRELIABLE,
-  SENSOR_ACCURACY_LOW,
-  SENSOR_ACCURACY_MED,
-  SENSOR_ACCURACY_HIGH,
-  NUM_SENSOR_ACCURACY_TYPE
-};
-
-class SensorAccuracy;
-
-typedef Observer<SensorAccuracy> ISensorAccuracyObserver;
-
 }
 }
 
+
 #include "IPC/IPCMessageUtils.h"
 
 namespace IPC {
   /**
    * Serializer for SensorType
    */
   template <>
   struct ParamTraits<mozilla::hal::SensorType>:
     public EnumSerializer<mozilla::hal::SensorType,
                           mozilla::hal::SENSOR_UNKNOWN,
                           mozilla::hal::NUM_SENSOR_TYPE> {
   };
 
-  template <>
-  struct ParamTraits<mozilla::hal::SensorAccuracyType>:
-    public EnumSerializer<mozilla::hal::SensorAccuracyType,
-                          mozilla::hal::SENSOR_ACCURACY_UNKNOWN,
-                          mozilla::hal::NUM_SENSOR_ACCURACY_TYPE> {
-
-  };
 } // namespace IPC
 
 #endif /* __HAL_SENSOR_H_ */
--- a/hal/Makefile.in
+++ b/hal/Makefile.in
@@ -41,17 +41,16 @@ srcdir      = @srcdir@
 VPATH       = \
   $(srcdir) \
   $(srcdir)/android \
   $(srcdir)/gonk \
   $(srcdir)/fallback \
   $(srcdir)/sandbox \
   $(srcdir)/linux \
   $(srcdir)/windows \
-  $(srcdir)/cocoa \
   $(NULL)
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = hal
 LIBRARY_NAME   = hal_s
 FORCE_STATIC_LIB = 1
 LIBXUL_LIBRARY = 1
@@ -95,24 +94,16 @@ ifdef MOZ_ENABLE_DBUS
 CPPSRCS += UPowerClient.cpp
 endif
 else ifeq (WINNT,$(OS_TARGET))
 CPPSRCS += \
   WindowsHal.cpp \
   WindowsBattery.cpp \
   FallbackSensor.cpp \
   $(NULL)
-else ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-CPPSRCS += \
-  FallbackHal.cpp \
-  $(NULL)
-CMMSRCS += \
-  CocoaSensor.mm \
-  smslib.mm \
-  $(NULL)
 else
 CPPSRCS += \
   FallbackHal.cpp \
   FallbackSensor.cpp \
   $(NULL)
 endif
 
 ifneq (gonk,$(MOZ_WIDGET_TOOLKIT)) #{
--- a/hal/android/AndroidSensor.cpp
+++ b/hal/android/AndroidSensor.cpp
@@ -38,20 +38,38 @@
 #include "Hal.h"
 #include "AndroidBridge.h"
 
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace hal_impl {
 
+/**
+ * Translate ID of sensor type from Sensor service to Android.
+ *
+ * Must be consistent with the definition of sensor types in
+ * embedding/android/GeckoAppShell.java
+ */
+static int
+MapSensorType(SensorType aSensorType) {
+  return (SENSOR_UNKNOWN <= aSensorType && aSensorType < NUM_SENSOR_TYPE) ?
+    aSensorType + 1 : -1;
+}
+
 void
 EnableSensorNotifications(SensorType aSensor) {
-  AndroidBridge::Bridge()->EnableSensor(aSensor);
+  int androidSensor = MapSensorType(aSensor);
+  
+  MOZ_ASSERT(androidSensor != -1);
+  AndroidBridge::Bridge()->EnableSensor(androidSensor);
 }
 
 void
 DisableSensorNotifications(SensorType aSensor) {
-  AndroidBridge::Bridge()->DisableSensor(aSensor);
+  int androidSensor = MapSensorType(aSensor);
+  
+  MOZ_ASSERT(androidSensor != -1);
+  AndroidBridge::Bridge()->DisableSensor(androidSensor);
 }
 
 } // hal_impl
 } // mozilla
deleted file mode 100644
--- a/hal/cocoa/CocoaSensor.mm
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "Hal.h"
-#include "nsITimer.h"
-
-#include "smslib.h"
-#define MEAN_GRAVITY 9.80665
-#define DEFAULT_SENSOR_POLL 100
-
-using namespace mozilla::hal;
-
-namespace mozilla {
-namespace hal_impl {
-
-static nsITimer* sUpdateTimer = nsnull;
-
-void UpdateHandler(nsITimer *aTimer, void *aClosure)
-{
-  sms_acceleration accel;
-  smsGetData(&accel);
-
-  InfallibleTArray<float> values;
-  values.AppendElement(accel.x * MEAN_GRAVITY);
-  values.AppendElement(accel.y * MEAN_GRAVITY);
-  values.AppendElement(accel.z * MEAN_GRAVITY);
-  hal::SensorData sdata(hal::SENSOR_ACCELERATION,
-			PR_Now(),
-			values,
-			hal::SENSOR_ACCURACY_UNKNOWN);
-  hal::NotifySensorChange(sdata);
-}
-
-void
-EnableSensorNotifications(SensorType aSensor) {
-  if (sUpdateTimer)
-    return;
-
-  smsStartup(nil, nil);
-  smsLoadCalibration();
-
-  CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
-  if (sUpdateTimer)
-    sUpdateTimer->InitWithFuncCallback(UpdateHandler,
-                                       NULL,
-                                       DEFAULT_SENSOR_POLL,
-                                       nsITimer::TYPE_REPEATING_SLACK);
-}
-
-void
-DisableSensorNotifications(SensorType aSensor) {
-  if (sUpdateTimer) {
-    sUpdateTimer->Cancel();
-    NS_RELEASE(sUpdateTimer);
-  }
-  smsShutdown();
-}
-
-} // hal_impl
-} // mozilla
--- a/hal/gonk/GonkSensor.cpp
+++ b/hal/gonk/GonkSensor.cpp
@@ -13,159 +13,107 @@
 #include "SensorDevice.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla::hal;
 using namespace android;
 
 namespace mozilla {
 
-#define DEFAULT_DEVICE_POLL_RATE 100000000 /*100ms*/
-
-
-double radToDeg(double a) {
-  return a * (180.0 / M_PI);
-}
-
 static SensorType
 HardwareSensorToHalSensor(int type)
 {     
   switch(type) {
     case SENSOR_TYPE_ORIENTATION:
       return SENSOR_ORIENTATION;
     case SENSOR_TYPE_ACCELEROMETER:
       return SENSOR_ACCELERATION;
     case SENSOR_TYPE_PROXIMITY:
       return SENSOR_PROXIMITY;
-    case SENSOR_TYPE_GYROSCOPE:
-      return SENSOR_GYROSCOPE;
-    case SENSOR_TYPE_LINEAR_ACCELERATION:
-      return SENSOR_LINEAR_ACCELERATION;
     default:
       return SENSOR_UNKNOWN;
   }
 }
 
-static SensorAccuracyType
-HardwareStatusToHalAccuracy(int status) {
-  return static_cast<SensorAccuracyType>(status);
-}
-
 static int
 HalSensorToHardwareSensor(SensorType type)
 {
   switch(type) {
     case SENSOR_ORIENTATION:
       return SENSOR_TYPE_ORIENTATION;
     case SENSOR_ACCELERATION:
       return SENSOR_TYPE_ACCELEROMETER;
     case SENSOR_PROXIMITY:
       return SENSOR_TYPE_PROXIMITY;
-    case SENSOR_GYROSCOPE:
-      return SENSOR_TYPE_GYROSCOPE;
-    case SENSOR_LINEAR_ACCELERATION:
-      return SENSOR_TYPE_LINEAR_ACCELERATION;
     default:
       return -1;
   }
 }
 
-static int
-SensorseventStatus(const sensors_event_t& data)
+static bool
+SensorseventToSensorData(const sensors_event_t& data, SensorData* aSensorData)
 {
-  int type = data.type;
-  switch(type) {
-    case SENSOR_ORIENTATION:
-      return data.orientation.status;
-    case SENSOR_LINEAR_ACCELERATION:
-    case SENSOR_ACCELERATION:
-      return data.acceleration.status;
-    case SENSOR_GYROSCOPE:
-      return data.gyro.status;
-  }
+  aSensorData->sensor() = HardwareSensorToHalSensor(data.type);
+
+  if (aSensorData->sensor() == SENSOR_UNKNOWN)
+    return false;
 
-
-  return SENSOR_STATUS_UNRELIABLE;
+  aSensorData->timestamp() = data.timestamp;
+  aSensorData->values()[0] = data.data[0];
+  aSensorData->values()[1] = data.data[1];
+  aSensorData->values()[2] = data.data[2];
+  return true;
 }
 
-class SensorRunnable : public nsRunnable
+static void
+onSensorChanged(const sensors_event_t& data, SensorData* aSensorData)
 {
-public:
-  SensorRunnable(const sensors_event_t& data)
-  {
-    mSensorData.sensor() = HardwareSensorToHalSensor(data.type);
-    mSensorData.accuracy() = HardwareStatusToHalAccuracy(SensorseventStatus(data));
-    mSensorData.timestamp() = data.timestamp;
-    if (mSensorData.sensor() == SENSOR_GYROSCOPE) {
-      // libhardware returns gyro as rad.  convert.
-      mSensorValues.AppendElement(radToDeg(data.data[0]));
-      mSensorValues.AppendElement(radToDeg(data.data[1]));
-      mSensorValues.AppendElement(radToDeg(data.data[2]));
-    } else {
-      mSensorValues.AppendElement(data.data[0]);
-      mSensorValues.AppendElement(data.data[1]);
-      mSensorValues.AppendElement(data.data[2]);
-    }
-    mSensorData.values() = mSensorValues;
-  }
-
-  ~SensorRunnable() {}
-
-  NS_IMETHOD Run()
-  {
-    NotifySensorChange(mSensorData);
-    return NS_OK;
-  }
-
-private:
-  SensorData mSensorData;
-  InfallibleTArray<float> mSensorValues;
-};
+  DebugOnly<bool> convertedData = SensorseventToSensorData(data, aSensorData);
+  MOZ_ASSERT(convertedData);
+  NotifySensorChange(*aSensorData);
+}
 
 namespace hal_impl {
 
 static pthread_t sThread;
-static bool sInitialized = false;
-static bool sContinue = true;
-static int sActivatedSensors = 0;
+static bool sInitialized;
+static bool sContinue;
+static int sActivatedSensors;
+static SensorData sSensordata[NUM_SENSOR_TYPE];
 static nsCOMPtr<nsIThread> sSwitchThread;
 
 static void*
 UpdateSensorData(void* /*unused*/)
 {
   SensorDevice &device = SensorDevice::getInstance();
   const size_t numEventMax = 16;
   sensors_event_t buffer[numEventMax];
   int count = 0;
 
   while (sContinue) {
     count = device.poll(buffer, numEventMax);
-
     if (count < 0) {
       continue;
     }
 
     for (int i=0; i<count; i++) {
-      if (SensorseventStatus(buffer[i]) == SENSOR_STATUS_UNRELIABLE) {
-        continue;
-      }
-      NS_DispatchToMainThread(new SensorRunnable(buffer[i]));
+      onSensorChanged(buffer[i], &sSensordata[HardwareSensorToHalSensor(buffer[i].type)]);
     }
   }
 
   return NULL;
 }
 
 static void 
 InitializeResources()
 {
+  pthread_create(&sThread, NULL, &UpdateSensorData, NULL);
+  NS_NewThread(getter_AddRefs(sSwitchThread));
   sInitialized = true;
   sContinue = true;
-  pthread_create(&sThread, NULL, &UpdateSensorData, NULL);
-  NS_NewThread(getter_AddRefs(sSwitchThread));
 }
 
 static void 
 ReleaseResources()
 {
   sContinue = false;
   pthread_join(sThread, NULL);
   sSwitchThread->Shutdown();
@@ -178,17 +126,16 @@ class SensorInfo {
     NS_INLINE_DECL_REFCOUNTING(SensorInfo)
 
     SensorInfo(bool aActivate, sensor_t aSensor, pthread_t aThreadId) :
                activate(aActivate), sensor(aSensor), threadId(aThreadId) { }
 
     void Switch() {
      SensorDevice& device = SensorDevice::getInstance();
      device.activate((void*)threadId, sensor.handle, activate);
-     device.setDelay((void*)threadId, sensor.handle, DEFAULT_DEVICE_POLL_RATE);
     }
 
   protected:
     SensorInfo() { };
     bool      activate;
     sensor_t  sensor;
     pthread_t threadId;
 };
@@ -233,10 +180,15 @@ DisableSensorNotifications(SensorType aS
   SensorSwitch(aSensor, false);  
   sActivatedSensors--;
 
   if (!sActivatedSensors) {
     ReleaseResources();  
   }
 }
 
+void 
+GetCurrentSensorDataInformation(SensorType aSensor, SensorData* aSensorData) {
+  *aSensorData = sSensordata[aSensor];
+}
+
 } // hal_impl
 } // mozilla
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -44,17 +44,16 @@ include "mozilla/HalSensor.h";
 include "mozilla/HalTypes.h";
 include "mozilla/dom/ScreenOrientation.h";
 
 using PRTime;
 using mozilla::hal::FlashMode;
 using mozilla::hal::LightType;
 using mozilla::hal::LightMode;
 using mozilla::hal::SensorType;
-using mozilla::hal::SensorAccuracyType;
 using mozilla::hal::WakeLockControl;
 using mozilla::dom::ScreenOrientation;
 
 namespace mozilla {
 
 namespace hal {
   struct BatteryInformation {
     double level;
@@ -70,17 +69,16 @@ namespace hal {
     uint32_t flashOffMS;
     uint32_t color;
   };
 
   struct SensorData {
     SensorType sensor;
     PRTime timestamp;
     float[] values;
-    SensorAccuracyType accuracy;
   };
 
   struct NetworkInformation {
     double bandwidth;
     bool   canBeMetered;
   };
 }
 
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -151,21 +151,19 @@ using mozilla::dom::gonk::AudioManager;
 #include "nsTextServicesDocument.h"
 #include "nsTextServicesCID.h"
 
 #include "nsScriptSecurityManager.h"
 #include "nsPrincipal.h"
 #include "nsSystemPrincipal.h"
 #include "nsNullPrincipal.h"
 #include "nsNetCID.h"
-#ifndef MOZ_WIDGET_GONK
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_PLATFORM_MAEMO)
 #include "nsHapticFeedback.h"
 #endif
-#endif
 #include "nsParserUtils.h"
 
 #define NS_EDITORCOMMANDTABLE_CID \
 { 0x4f5e62b8, 0xd659, 0x4156, { 0x84, 0xfc, 0x2f, 0x60, 0x99, 0x40, 0x03, 0x69 }}
 
 #define NS_EDITINGCOMMANDTABLE_CID \
 { 0xcb38a746, 0xbeb8, 0x43f3, { 0x94, 0x29, 0x77, 0x96, 0xe1, 0xa9, 0x3f, 0xb4 }}
 
@@ -238,17 +236,24 @@ NS_NewXULTreeBuilder(nsISupports* aOuter
 static void Shutdown();
 
 #ifdef MOZ_XTF
 #include "nsIXTFService.h"
 #include "nsIXMLContentBuilder.h"
 #endif
 
 #include "nsGeolocation.h"
-#include "nsDeviceMotion.h"
+#ifndef MOZ_WIDGET_GONK
+#if defined(XP_UNIX)    || \
+    defined(_WINDOWS)   || \
+    defined(machintosh) || \
+    defined(android)
+#include "nsDeviceMotionSystem.h"
+#endif
+#endif
 #include "nsCSPService.h"
 #include "nsISmsService.h"
 #include "nsISmsDatabaseService.h"
 #include "mozilla/dom/sms/SmsRequestManager.h"
 #include "mozilla/dom/sms/SmsServicesFactory.h"
 #include "nsIPowerManagerService.h"
 
 using namespace mozilla::dom::sms;
@@ -286,20 +291,23 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
                                          DOMRequestService::FactoryCreate)
 #ifdef MOZ_B2G_RIL
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(SystemWorkerManager,
                                          SystemWorkerManager::FactoryCreate)
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 NS_GENERIC_FACTORY_CONSTRUCTOR(AudioManager)
+#else
+#if defined(XP_UNIX)    || \
+    defined(_WINDOWS)   || \
+    defined(machintosh) || \
+    defined(android)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceMotionSystem)
 #endif
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceMotion)
-
-#ifndef MOZ_WIDGET_GONK
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHapticFeedback)
 #endif
 #endif
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ThirdPartyUtil, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsService, SmsServicesFactory::CreateSmsService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsDatabaseService, SmsServicesFactory::CreateSmsDatabaseService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPowerManagerService,
@@ -780,19 +788,24 @@ NS_DEFINE_NAMED_CID(NS_CHILDPROCESSMESSA
 NS_DEFINE_NAMED_CID(NSCHANNELPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTSECURITYMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_PRINCIPAL_CID);
 NS_DEFINE_NAMED_CID(NS_SYSTEMPRINCIPAL_CID);
 NS_DEFINE_NAMED_CID(NS_NULLPRINCIPAL_CID);
 NS_DEFINE_NAMED_CID(NS_SECURITYNAMESET_CID);
 NS_DEFINE_NAMED_CID(THIRDPARTYUTIL_CID);
 NS_DEFINE_NAMED_CID(NS_STRUCTUREDCLONECONTAINER_CID);
-NS_DEFINE_NAMED_CID(NS_DEVICE_MOTION_CID);
 
 #ifndef MOZ_WIDGET_GONK
+#if defined(XP_UNIX)    || \
+    defined(_WINDOWS)   || \
+    defined(machintosh) || \
+    defined(android)
+NS_DEFINE_NAMED_CID(NS_DEVICE_MOTION_CID);
+#endif
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
 NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CID);
 #endif
 #endif
 NS_DEFINE_NAMED_CID(SMS_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_DATABASE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_REQUEST_MANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID);
@@ -1049,18 +1062,23 @@ static const mozilla::Module::CIDEntry k
   { &kNS_PARENTPROCESSMESSAGEMANAGER_CID, false, NULL, CreateParentMessageManager },
   { &kNS_CHILDPROCESSMESSAGEMANAGER_CID, false, NULL, CreateChildMessageManager },
   { &kNSCHANNELPOLICY_CID, false, NULL, nsChannelPolicyConstructor },
   { &kNS_SCRIPTSECURITYMANAGER_CID, false, NULL, Construct_nsIScriptSecurityManager },
   { &kNS_PRINCIPAL_CID, false, NULL, nsPrincipalConstructor },
   { &kNS_SYSTEMPRINCIPAL_CID, false, NULL, nsSystemPrincipalConstructor },
   { &kNS_NULLPRINCIPAL_CID, false, NULL, nsNullPrincipalConstructor },
   { &kNS_SECURITYNAMESET_CID, false, NULL, nsSecurityNameSetConstructor },
-  { &kNS_DEVICE_MOTION_CID, false, NULL, nsDeviceMotionConstructor },
 #ifndef MOZ_WIDGET_GONK
+#if defined(XP_UNIX)    || \
+    defined(_WINDOWS)   || \
+    defined(machintosh) || \
+    defined(android)
+  { &kNS_DEVICE_MOTION_CID, false, NULL, nsDeviceMotionSystemConstructor },
+#endif
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
   { &kNS_HAPTICFEEDBACK_CID, false, NULL, nsHapticFeedbackConstructor },
 #endif
 #endif
   { &kTHIRDPARTYUTIL_CID, false, NULL, ThirdPartyUtilConstructor },
   { &kNS_STRUCTUREDCLONECONTAINER_CID, false, NULL, nsStructuredCloneContainerConstructor },
   { &kSMS_SERVICE_CID, false, NULL, nsISmsServiceConstructor },
   { &kSMS_DATABASE_SERVICE_CID, false, NULL, nsISmsDatabaseServiceConstructor },
@@ -1183,18 +1201,23 @@ static const mozilla::Module::ContractID
   { NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID, &kNS_CHILDPROCESSMESSAGEMANAGER_CID },
   { NSCHANNELPOLICY_CONTRACTID, &kNSCHANNELPOLICY_CID },
   { NS_SCRIPTSECURITYMANAGER_CONTRACTID, &kNS_SCRIPTSECURITYMANAGER_CID },
   { NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID, &kNS_SCRIPTSECURITYMANAGER_CID },
   { NS_PRINCIPAL_CONTRACTID, &kNS_PRINCIPAL_CID },
   { NS_SYSTEMPRINCIPAL_CONTRACTID, &kNS_SYSTEMPRINCIPAL_CID },
   { NS_NULLPRINCIPAL_CONTRACTID, &kNS_NULLPRINCIPAL_CID },
   { NS_SECURITYNAMESET_CONTRACTID, &kNS_SECURITYNAMESET_CID },
+#ifndef MOZ_WIDGET_GONK
+#if defined(XP_UNIX)    || \
+    defined(_WINDOWS)   || \
+    defined(machintosh) || \
+    defined(android)
   { NS_DEVICE_MOTION_CONTRACTID, &kNS_DEVICE_MOTION_CID },
-#ifndef MOZ_WIDGET_GONK
+#endif
 #if defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
   { "@mozilla.org/widget/hapticfeedback;1", &kNS_HAPTICFEEDBACK_CID },
 #endif
 #endif
   { THIRDPARTYUTIL_CONTRACTID, &kTHIRDPARTYUTIL_CID },
   { NS_STRUCTUREDCLONECONTAINER_CONTRACTID, &kNS_STRUCTUREDCLONECONTAINER_CID },
   { SMS_SERVICE_CONTRACTID, &kSMS_SERVICE_CID },
   { SMS_DATABASE_SERVICE_CONTRACTID, &kSMS_DATABASE_SERVICE_CID },
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -2785,27 +2785,33 @@ abstract public class GeckoApp
         Log.i(LOGTAG, "Sending message to Gecko: " + SystemClock.uptimeMillis() + " - Tab:Add");
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Add", args.toString()));
     }
 
     public GeckoLayerClient getLayerClient() { return mLayerClient; }
     public LayerController getLayerController() { return mLayerController; }
 
     // accelerometer
-    public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+    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));
     }
 
     // geolocation
     public void onLocationChanged(Location location)
     {
         Log.w(LOGTAG, "onLocationChanged "+location);
+
         GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location));
     }
 
     public void onProviderDisabled(String provider)
     {
     }
 
     public void onProviderEnabled(String provider)
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -580,95 +580,82 @@ public class GeckoAppShell
     }
 
     public static void enableSensor(int aSensortype) {
         SensorManager sm = (SensorManager)
             GeckoApp.mAppContext.getSystemService(Context.SENSOR_SERVICE);
 
         switch(aSensortype) {
         case GeckoHalDefines.SENSOR_ORIENTATION:
-            Log.i(LOGTAG, "Enabling 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:
-            Log.i(LOGTAG, "Enabling 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:
-            Log.i(LOGTAG, "Enabling SENSOR_PROXIMITY");
             if(gProximitySensor == null)
                 gProximitySensor = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
             if (gProximitySensor != null)
                 sm.registerListener(GeckoApp.mAppContext, gProximitySensor, sDefaultSensorHint);
             break;
 
         case GeckoHalDefines.SENSOR_LINEAR_ACCELERATION:
-            Log.i(LOGTAG, "Enabling SENSOR_LINEAR_ACCELERATION");
             if(gLinearAccelerometerSensor == null)
-                gLinearAccelerometerSensor = sm.getDefaultSensor(10 /* API Level 9 - TYPE_LINEAR_ACCELERATION */);
+                gLinearAccelerometerSensor = sm.getDefaultSensor(10);
             if (gLinearAccelerometerSensor != null)
                 sm.registerListener(GeckoApp.mAppContext, gLinearAccelerometerSensor, sDefaultSensorHint);
             break;
 
         case GeckoHalDefines.SENSOR_GYROSCOPE:
-            Log.i(LOGTAG, "Enabling SENSOR_GYROSCOPE");
             if(gGyroscopeSensor == null)
                 gGyroscopeSensor = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
             if (gGyroscopeSensor != null)
                 sm.registerListener(GeckoApp.mAppContext, gGyroscopeSensor, sDefaultSensorHint);
             break;
-        default:
-            Log.e(LOGTAG, "Error! SENSOR type used " + aSensortype);
+
         }
     }
 
     public static void disableSensor(int aSensortype) {
         SensorManager sm = (SensorManager)
             GeckoApp.mAppContext.getSystemService(Context.SENSOR_SERVICE);
 
         switch (aSensortype) {
         case GeckoHalDefines.SENSOR_ORIENTATION:
-            Log.i(LOGTAG, "Disabling SENSOR_ORIENTATION");
             if (gOrientationSensor != null)
                 sm.unregisterListener(GeckoApp.mAppContext, gOrientationSensor);
             break;
 
         case GeckoHalDefines.SENSOR_ACCELERATION:
-            Log.i(LOGTAG, "Disabling SENSOR_ACCELERATION");
             if (gAccelerometerSensor != null)
                 sm.unregisterListener(GeckoApp.mAppContext, gAccelerometerSensor);
             break;
 
         case GeckoHalDefines.SENSOR_PROXIMITY:
-            Log.i(LOGTAG, "Disabling SENSOR_PROXIMITY");
             if (gProximitySensor != null)
                 sm.unregisterListener(GeckoApp.mAppContext, gProximitySensor);
             break;
 
         case GeckoHalDefines.SENSOR_LINEAR_ACCELERATION:
-            Log.i(LOGTAG, "Disabling SENSOR_LINEAR_ACCELERATION");
             if (gLinearAccelerometerSensor != null)
                 sm.unregisterListener(GeckoApp.mAppContext, gLinearAccelerometerSensor);
             break;
 
         case GeckoHalDefines.SENSOR_GYROSCOPE:
-            Log.i(LOGTAG, "Disabling SENSOR_GYROSCOPE");
             if (gGyroscopeSensor != null)
                 sm.unregisterListener(GeckoApp.mAppContext, gGyroscopeSensor);
             break;
-        default:
-            Log.e(LOGTAG, "Error! SENSOR type used " + aSensortype);
         }
     }
 
     public static void moveTaskToBack() {
         GeckoApp.mAppContext.moveTaskToBack(true);
     }
 
     public static void returnIMEQueryResult(String result, int selectionStart, int selectionLength) {
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -66,36 +66,38 @@ import android.util.Log;
 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 LOCATION_EVENT = 4;
-    private static final int IME_EVENT = 5;
-    private static final int DRAW = 6;
-    private static final int SIZE_CHANGED = 7;
-    private static final int ACTIVITY_STOPPING = 8;
-    private static final int ACTIVITY_PAUSING = 9;
-    private static final int ACTIVITY_SHUTDOWN = 10;
-    private static final int LOAD_URI = 11;
-    private static final int SURFACE_CREATED = 12;
-    private static final int SURFACE_DESTROYED = 13;
-    private static final int GECKO_EVENT_SYNC = 14;
-    private static final int FORCED_RESIZE = 15;
-    private static final int ACTIVITY_START = 16;
-    private static final int BROADCAST = 17;
-    private static final int VIEWPORT = 18;
-    private static final int VISITED = 19;
-    private static final int NETWORK_CHANGED = 20;
-    private static final int ACTIVITY_RESUMING = 21;
-    private static final int SCREENSHOT = 22;
-    private static final int SCREENORIENTATION_CHANGED = 23;
+    private static final int UNUSED1_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;
+    private static final int SURFACE_CREATED = 13;
+    private static final int SURFACE_DESTROYED = 14;
+    private static final int GECKO_EVENT_SYNC = 15;
+    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;
+    private static final int SCREENORIENTATION_CHANGED = 27;
 
     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 +119,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 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;
     public Location mLocation;
@@ -275,76 +278,59 @@ public class GeckoEvent {
             mPressures[index] = event.getPressure(eventIndex);
         } catch(Exception ex) {
             Log.e(LOGTAG, "Error creating motion point " + index, ex);
             mPointRadii[index] = new Point(0, 0);
             mPoints[index] = new Point(0, 0);
         }
     }
 
-    private static int HalSensorAccuracyFor(int androidAccuracy) {
-        switch (androidAccuracy) {
-        case SensorManager.SENSOR_STATUS_UNRELIABLE:
-            return GeckoHalDefines.SENSOR_ACCURACY_UNRELIABLE;
-        case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
-            return GeckoHalDefines.SENSOR_ACCURACY_LOW;
-        case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
-            return GeckoHalDefines.SENSOR_ACCURACY_MED;
-        case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
-            return GeckoHalDefines.SENSOR_ACCURACY_HIGH;
-        }
-        return GeckoHalDefines.SENSOR_ACCURACY_UNKNOWN;
-    }
-
     public static GeckoEvent createSensorEvent(SensorEvent s) {
         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.mMetaState = HalSensorAccuracyFor(s.accuracy);
             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.mMetaState = HalSensorAccuracyFor(s.accuracy);
             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.mMetaState = HalSensorAccuracyFor(s.accuracy);
             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.mMetaState = HalSensorAccuracyFor(s.accuracy);
             event.mX = Math.toDegrees(s.values[0]);
             event.mY = Math.toDegrees(s.values[1]);
             event.mZ = Math.toDegrees(s.values[2]);
             break;
 
         case Sensor.TYPE_PROXIMITY:
-            event = new GeckoEvent(SENSOR_EVENT);
-            event.mFlags = GeckoHalDefines.SENSOR_PROXIMITY;
-            event.mX = s.values[0];
+            // 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) {
         GeckoEvent event = new GeckoEvent(LOCATION_EVENT);
         event.mLocation = l;
@@ -450,14 +436,20 @@ public class GeckoEvent {
         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;
+    }
+
     public static GeckoEvent createScreenOrientationEvent(short aScreenOrientation) {
         GeckoEvent event = new GeckoEvent(SCREENORIENTATION_CHANGED);
         event.mScreenOrientation = aScreenOrientation;
         return event;
     }
 }
--- a/mobile/android/base/GeckoHalDefines.java
+++ b/mobile/android/base/GeckoHalDefines.java
@@ -41,15 +41,9 @@ 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;
-
-    public static final int SENSOR_ACCURACY_UNKNOWN = -1;
-    public static final int SENSOR_ACCURACY_UNRELIABLE = 0;
-    public static final int SENSOR_ACCURACY_LOW = 1;
-    public static final int SENSOR_ACCURACY_MED = 2;
-    public static final int SENSOR_ACCURACY_HIGH = 3;
 };
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -314,16 +314,38 @@ AndroidBridge::AcknowledgeEventSync()
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     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);
+    }
+}
+
+
+void
 AndroidBridge::EnableLocation(bool aEnable)
 {
     ALOG_BRIDGE("AndroidBridge::EnableLocation");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -171,16 +171,18 @@ public:
                                  const nsAString& aActionHint);
 
     static void NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen, int aStart, int aEnd, int aNewEnd);
 
     nsresult TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId, float scale);
 
     void AcknowledgeEventSync();
 
+    void EnableDeviceMotion(bool aEnable);
+
     void EnableLocation(bool aEnable);
 
     void EnableSensor(int aSensorType);
 
     void DisableSensor(int aSensorType);
 
     void ReturnIMEQueryResult(const PRUnichar *aResult, PRUint32 aLen, int aSelStart, int aSelLen);
 
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -160,16 +160,17 @@ AndroidGeckoEvent::InitGeckoEventClass(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;");
     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;");
     jKeyCodeField = getField("mKeyCode", "I");
     jMetaStateField = getField("mMetaState", "I");
     jFlagsField = getField("mFlags", "I");
     jUnicodeCharField = getField("mUnicodeChar", "I");
@@ -469,17 +470,16 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
             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);
-             mMetaState = jenv->GetIntField(jobj, jMetaStateField);
              break;
 
         case LOCATION_EVENT: {
             jobject location = jenv->GetObjectField(jobj, jLocationField);
             mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location);
             break;
         }
 
@@ -501,16 +501,22 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
             break;
         }
 
         case VISITED: {
             ReadCharactersField(jenv);
             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;
         }
 
@@ -523,17 +529,17 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
             mScreenOrientation = jenv->GetShortField(jobj, jScreenOrientationField);
             break;
         }
 
         default:
             break;
     }
 
-#ifdef DEBUG_ANDROID_EVENTS
+#ifndef DEBUG_ANDROID_EVENTS
     ALOG("AndroidGeckoEvent: %p : %d", (void*)jobj, mType);
 #endif
 }
 
 void
 AndroidGeckoEvent::Init(int aType)
 {
     mType = aType;
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -461,16 +461,17 @@ public:
     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 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; }
     int MetaState() { return mMetaState; }
     int Flags() { return mFlags; }
     int UnicodeChar() { return mUnicodeChar; }
     int Offset() { return mOffset; }
@@ -562,36 +563,39 @@ protected:
     static jfieldID jScreenOrientationField;
 
 public:
     enum {
         NATIVE_POKE = 0,
         KEY_EVENT = 1,
         MOTION_EVENT = 2,
         SENSOR_EVENT = 3,
-        LOCATION_EVENT = 4,
-        IME_EVENT = 5,
-        DRAW = 6,
-        SIZE_CHANGED = 7,
-        ACTIVITY_STOPPING = 8,
-        ACTIVITY_PAUSING = 9,
-        ACTIVITY_SHUTDOWN = 10,
-        LOAD_URI = 11,
-        SURFACE_CREATED = 12,
-        SURFACE_DESTROYED = 13,
-        GECKO_EVENT_SYNC = 14,
-        FORCED_RESIZE = 15,
-        ACTIVITY_START = 16,
-        BROADCAST = 17,
-        VIEWPORT = 18,
-        VISITED = 19,
-        NETWORK_CHANGED = 20,
-        ACTIVITY_RESUMING = 21,
-        SCREENSHOT = 22,
-        SCREENORIENTATION_CHANGED = 23,
+        UNUSED1_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,
+        SURFACE_CREATED = 13,
+        SURFACE_DESTROYED = 14,
+        GECKO_EVENT_SYNC = 15,
+        FORCED_RESIZE = 16,
+        ACTIVITY_START = 17,
+        BROADCAST = 19,
+        VIEWPORT = 20,
+        VISITED = 21,
+        NETWORK_CHANGED = 22,
+        PROXIMITY_EVENT = 23,
+        ACTIVITY_RESUMING = 24,
+        SCREENSHOT = 25,
+        SENSOR_ACCURACY = 26,
+        SCREENORIENTATION_CHANGED = 27,
         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
@@ -51,16 +51,17 @@
 
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Hal.h"
 #include "prenv.h"
 
 #include "AndroidBridge.h"
+#include "nsDeviceMotionSystem.h"
 #include <android/log.h>
 #include <pthread.h>
 #include <wchar.h>
 
 #include "mozilla/dom/ScreenOrientation.h"
 
 #ifdef MOZ_ANDROID_HISTORY
 #include "nsAndroidHistory.h"
@@ -78,16 +79,17 @@
 #endif
 
 using namespace mozilla;
 
 #ifdef PR_LOGGING
 PRLogModuleInfo *gWidgetLog = nsnull;
 #endif
 
+nsDeviceMotionSystem *gDeviceMotionSystem = nsnull;
 nsIGeolocationUpdate *gLocationCallback = nsnull;
 nsAutoPtr<mozilla::AndroidGeckoEvent> gLastSizeChange;
 
 nsAppShell *nsAppShell::gAppShell = nsnull;
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
 
 nsAppShell::nsAppShell()
@@ -326,65 +328,78 @@ 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_EVENT:
-      {
-        mPendingSensorEvents = false;
-        InfallibleTArray<float> values;
-        mozilla::hal::SensorType type = (mozilla::hal::SensorType) curEvent->Flags();
+    case AndroidGeckoEvent::SENSOR_ACCURACY:
+        if (curEvent->Flags() == 0)
+            gDeviceMotionSystem->NeedsCalibration();
+        break;
 
-        switch (type) {
-          case hal::SENSOR_ORIENTATION:
-            values.AppendElement(curEvent->X());
-            values.AppendElement(-curEvent->Y()); 
-            values.AppendElement(-curEvent->Z());
+    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:
-          case hal::SENSOR_LINEAR_ACCELERATION:
-          case hal::SENSOR_GYROSCOPE:
-            values.AppendElement(-curEvent->X());
-            values.AppendElement(curEvent->Y());
-            values.AppendElement(curEvent->Z());
+        case hal::SENSOR_ACCELERATION:
+            gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
+                                                     -curEvent->X(),
+                                                     curEvent->Y(),
+                                                     curEvent->Z());
             break;
 
-        case hal::SENSOR_PROXIMITY:
-            values.AppendElement(curEvent->X());
+        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",
-                                type);
+            __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### SENSOR_EVENT fired, but type wasn't known %d", curEvent->Flags());
         }
-
-        const hal::SensorAccuracyType &accuracy = (hal::SensorAccuracyType) curEvent->MetaState();
-        hal::SensorData sdata(type, PR_Now(), values, accuracy);
-        hal::NotifySensorChange(sdata);
-      }
-      break;
+         break;
 
     case AndroidGeckoEvent::LOCATION_EVENT: {
         if (!gLocationCallback)
             break;
 
         nsGeoPosition* p = curEvent->GeoPosition();
         if (p)
             gLocationCallback->Update(curEvent->GeoPosition());
         else
             NS_WARNING("Received location event without geoposition!");
         break;
     }
 
+    case AndroidGeckoEvent::PROXIMITY_EVENT: {
+        InfallibleTArray<float> values;
+        values.AppendElement(curEvent->Distance());
+        
+        hal::SensorData sdata(hal::SENSOR_PROXIMITY, PR_Now(), values);
+        hal::NotifySensorChange(sdata);
+        break;
+    }
+
     case AndroidGeckoEvent::ACTIVITY_STOPPING: {
         if (curEvent->Flags() > 0)
             break;
 
         nsCOMPtr<nsIObserverService> obsServ =
             mozilla::services::GetObserverService();
         NS_NAMED_LITERAL_STRING(minimize, "heap-minimize");
         obsServ->NotifyObservers(nsnull, "memory-pressure", minimize.get());
--- a/xpcom/system/nsIDeviceMotion.idl
+++ b/xpcom/system/nsIDeviceMotion.idl
@@ -36,22 +36,20 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMWindow;
 
 [scriptable, uuid(1B406E32-CF42-471E-A470-6FD600BF4C7B)]
 interface nsIDeviceMotionData : nsISupports
 {
-  // Keep in sync with hal/HalSensor.h
-  const unsigned long TYPE_ORIENTATION = 0;
-  const unsigned long TYPE_ACCELERATION = 1;
-  const unsigned long TYPE_PROXIMITY = 2;
-  const unsigned long TYPE_LINEAR_ACCELERATION = 3;
-  const unsigned long TYPE_GYROSCOPE = 4;
+  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;
 };
 
@@ -69,8 +67,19 @@ interface nsIDeviceMotion : nsISupports
   void removeListener(in nsIDeviceMotionListener aListener);
 
   // Holds pointers, not AddRef objects -- it is up to the caller
   // to call RemoveWindowListener before the window is deleted.
   [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)]
+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();
+};