Bug 738131 - implement device proximity. r=smaug
authorDoug Turner <dougt@dougt.org>
Wed, 02 May 2012 09:43:45 -0700
changeset 93115 1aa618c21bab21a4fb1bb42870828f70a6fbb8d1
parent 93114 270db83fa61c70447ac02a5643b9dfaca3c798e7
child 93116 bbdf0f8c06a8274828ff5d8b0a9f7756b399493d
push id730
push usertim.taubert@gmx.de
push dateFri, 04 May 2012 14:23:10 +0000
treeherderfx-team@b6e6a24c9e95 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs738131
milestone15.0a1
Bug 738131 - implement device proximity. r=smaug * * * Bug 738131 - implement device proximity. gonk implementation. r=mwu
content/base/src/nsGkAtomList.h
content/events/public/nsEventNameList.h
content/events/public/nsIPrivateDOMEvent.h
content/events/src/Makefile.in
content/events/src/nsDOMDeviceProximityEvent.cpp
content/events/src/nsDOMDeviceProximityEvent.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/events/src/nsEventListenerManager.cpp
content/events/test/test_eventctors.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/interfaces/base/nsIDOMWindow.idl
dom/interfaces/events/Makefile.in
dom/interfaces/events/nsIDOMDeviceProximityEvent.idl
dom/system/nsDeviceSensors.cpp
dom/system/nsDeviceSensors.h
hal/gonk/GonkSensor.cpp
js/xpconnect/src/dictionary_helper_gen.conf
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoEvent.java
widget/nsGUIEvent.h
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1706,18 +1706,19 @@ GK_ATOM(onMozTapGesture, "onMozTapGestur
 GK_ATOM(onMozPressTapGesture, "onMozPressTapGesture")
 
 // Touch events
 GK_ATOM(onMozTouchDown, "onMozTouchDown")
 GK_ATOM(onMozTouchMove, "onMozTouchMove")
 GK_ATOM(onMozTouchUp, "onMozTouchUp")
 
 // orientation support
+GK_ATOM(ondevicemotion, "ondevicemotion")
 GK_ATOM(ondeviceorientation, "ondeviceorientation")
-GK_ATOM(ondevicemotion, "ondevicemotion")
+GK_ATOM(ondeviceproximity, "ondeviceproximity")
 
 //---------------------------------------------------------------------------
 // Special atoms
 //---------------------------------------------------------------------------
 
 // Node types
 GK_ATOM(cdataTagName, "#cdata-section")
 GK_ATOM(commentTagName, "#comment")
--- a/content/events/public/nsEventNameList.h
+++ b/content/events/public/nsEventNameList.h
@@ -450,16 +450,20 @@ WINDOW_EVENT(unload,
 WINDOW_ONLY_EVENT(devicemotion,
                   NS_DEVICE_MOTION,
                   EventNameType_None,
                   NS_EVENT)
 WINDOW_ONLY_EVENT(deviceorientation,
                   NS_DEVICE_ORIENTATION,
                   EventNameType_None,
                   NS_EVENT)
+WINDOW_ONLY_EVENT(deviceproximity,
+                  NS_DEVICE_PROXIMITY,
+                  EventNameType_None,
+                  NS_EVENT)
 
 TOUCH_EVENT(touchstart,
             NS_TOUCH_START,
             EventNameType_All,
             NS_TOUCH_EVENT)
 TOUCH_EVENT(touchend,
             NS_TOUCH_END,
             EventNameType_All,
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -87,16 +87,18 @@ nsresult
 NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
 nsresult
 NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsCompositionEvent *aEvent);
 nsresult
 NS_NewDOMMutationEvent(nsIDOMEvent** aResult NS_OUTPARAM, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
 nsresult
 NS_NewDOMPopupBlockedEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
+NS_NewDOMDeviceProximityEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
+nsresult
 NS_NewDOMDeviceOrientationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
 NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
 NS_NewDOMTextEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsTextEvent* aEvent);
 nsresult
 NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
 nsresult
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -46,30 +46,31 @@ MODULE		= content
 LIBRARY_NAME	= gkconevents_s
 LIBXUL_LIBRARY  = 1
 
 EXPORTS		= \
 		nsEventStateManager.h \
 		nsEventListenerManager.h \
 		nsDOMEventTargetHelper.h \
 		$(NULL)
-		
+
 CPPSRCS		= \
 		nsEventListenerManager.cpp \
 		nsEventStateManager.cpp \
 		nsDOMEvent.cpp \
 		nsDOMDataContainerEvent.cpp \
 		nsDOMUIEvent.cpp \
 		nsDOMKeyboardEvent.cpp \
 		nsDOMTextEvent.cpp \
 		nsDOMMouseEvent.cpp \
 		nsDOMMouseScrollEvent.cpp \
 		nsDOMDragEvent.cpp \
 		nsDOMMutationEvent.cpp \
 		nsDOMPopupBlockedEvent.cpp \
+		nsDOMDeviceProximityEvent.cpp \
 		nsDOMDeviceOrientationEvent.cpp \
 		nsDOMDeviceMotionEvent.cpp \
 		nsDOMBeforeUnloadEvent.cpp \
 		nsDOMPageTransitionEvent.cpp \
 		nsDOMXULCommandEvent.cpp \
 		nsDOMCommandEvent.cpp \
 		nsDOMMessageEvent.cpp \
 		nsPaintRequest.cpp \
new file mode 100644
--- /dev/null
+++ b/content/events/src/nsDOMDeviceProximityEvent.cpp
@@ -0,0 +1,81 @@
+/* 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 "nsDOMDeviceProximityEvent.h"
+#include "nsContentUtils.h"
+#include "DictionaryHelpers.h"
+
+NS_IMPL_ADDREF_INHERITED(nsDOMDeviceProximityEvent, nsDOMEvent)
+NS_IMPL_RELEASE_INHERITED(nsDOMDeviceProximityEvent, nsDOMEvent)
+
+DOMCI_DATA(DeviceProximityEvent, nsDOMDeviceProximityEvent)
+
+NS_INTERFACE_MAP_BEGIN(nsDOMDeviceProximityEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceProximityEvent)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceProximityEvent)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
+
+NS_IMETHODIMP
+nsDOMDeviceProximityEvent::InitDeviceProximityEvent(const nsAString & aEventTypeArg,
+                                                    bool aCanBubbleArg,
+                                                    bool aCancelableArg,
+                                                    double aValue,
+                                                    double aMin,
+                                                    double aMax)
+{
+  nsresult rv = nsDOMEvent::InitEvent(aEventTypeArg, aCanBubbleArg, aCancelableArg);
+  NS_ENSURE_SUCCESS(rv, rv);
+    
+  mValue = aValue;
+  mMin = aMin;
+  mMax = aMax;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceProximityEvent::GetValue(double *aValue)
+{
+  NS_ENSURE_ARG_POINTER(aValue);
+
+  *aValue = mValue;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceProximityEvent::GetMin(double *aMin)
+{
+  NS_ENSURE_ARG_POINTER(aMin);
+
+  *aMin = mMin;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceProximityEvent::GetMax(double *aMax)
+{
+  NS_ENSURE_ARG_POINTER(aMax);
+
+  *aMax = mMax;
+  return NS_OK;
+}
+
+nsresult
+nsDOMDeviceProximityEvent::InitFromCtor(const nsAString& aType,
+                                        JSContext* aCx, jsval* aVal)
+{
+  mozilla::dom::DeviceProximityEventInit d;
+  nsresult rv = d.Init(aCx, aVal);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return InitDeviceProximityEvent(aType, d.bubbles, d.cancelable, d.value, d.min, d.max);
+}
+
+nsresult
+NS_NewDOMDeviceProximityEvent(nsIDOMEvent** aInstancePtrResult,
+                              nsPresContext* aPresContext,
+                              nsEvent *aEvent)
+{
+  NS_ENSURE_ARG_POINTER(aInstancePtrResult);
+  nsDOMDeviceProximityEvent* it = new nsDOMDeviceProximityEvent(aPresContext, aEvent);
+  return CallQueryInterface(it, aInstancePtrResult);
+}
new file mode 100644
--- /dev/null
+++ b/content/events/src/nsDOMDeviceProximityEvent.h
@@ -0,0 +1,38 @@
+/* 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/. */
+
+#ifndef nsDOMDeviceProximityEvent_h__
+#define nsDOMDeviceProximityEvent_h__
+
+#include "nsIDOMDeviceProximityEvent.h"
+#include "nsDOMEvent.h"
+
+class nsDOMDeviceProximityEvent
+ : public nsDOMEvent
+ , public nsIDOMDeviceProximityEvent
+{
+public:
+
+ nsDOMDeviceProximityEvent(nsPresContext* aPresContext, nsEvent* aEvent)
+  : nsDOMEvent(aPresContext, aEvent),
+    mValue(-1),
+    mMin(0),
+    mMax(0) {}
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // Forward to nsDOMEvent
+  NS_FORWARD_TO_NSDOMEVENT
+
+  // nsIDOMDeviceProximityEvent Interface
+  NS_DECL_NSIDOMDEVICEPROXIMITYEVENT
+
+  virtual nsresult InitFromCtor(const nsAString& aType,
+                                JSContext* aCx,
+                                jsval* aVal);
+protected:
+  double mValue, mMin, mMax;
+};
+
+#endif
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -121,17 +121,18 @@ static const char* const sEventNames[] =
   "touchenter",
   "touchleave",
   "MozScrolledAreaChanged",
   "transitionend",
   "animationstart",
   "animationend",
   "animationiteration",
   "devicemotion",
-  "deviceorientation"
+  "deviceorientation",
+  "deviceproximity"
 };
 
 static char *sPopupAllowedEvents;
 
 
 nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
 {
   mPrivateDataDuplicated = false;
@@ -1548,16 +1549,18 @@ const char* nsDOMEvent::GetEventName(PRU
   case NS_ANIMATION_END:
     return sEventNames[eDOMEvents_animationend];
   case NS_ANIMATION_ITERATION:
     return sEventNames[eDOMEvents_animationiteration];
   case NS_DEVICE_MOTION:
     return sEventNames[eDOMEvents_devicemotion];
   case NS_DEVICE_ORIENTATION:
     return sEventNames[eDOMEvents_deviceorientation];
+  case NS_DEVICE_PROXIMITY:
+    return sEventNames[eDOMEvents_deviceproximity];
   case NS_FULLSCREENCHANGE:
     return sEventNames[eDOMEvents_mozfullscreenchange];
   case NS_FULLSCREENERROR:
     return sEventNames[eDOMEvents_mozfullscreenerror];
   default:
     break;
   }
   // XXXldb We can hit this case for nsEvent objects that we didn't
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -204,17 +204,18 @@ public:
     eDOMEvents_touchenter,
     eDOMEvents_touchleave,
     eDOMEvents_MozScrolledAreaChanged,
     eDOMEvents_transitionend,
     eDOMEvents_animationstart,
     eDOMEvents_animationend,
     eDOMEvents_animationiteration,
     eDOMEvents_devicemotion,
-    eDOMEvents_deviceorientation
+    eDOMEvents_deviceorientation,
+    eDOMEvents_deviceproximity
   };
 
   nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);
   virtual ~nsDOMEvent();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMEvent, nsIDOMEvent)
 
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -285,16 +285,18 @@ nsEventListenerManager::AddEventListener
       // If aType is NS_MUTATION_SUBTREEMODIFIED, we need to listen all
       // mutations. nsContentUtils::HasMutationListeners relies on this.
       window->SetMutationListeners((aType == NS_MUTATION_SUBTREEMODIFIED) ?
                                    kAllMutationBits :
                                    MutationBitForEventType(aType));
     }
   } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) {
     EnableDevice(NS_DEVICE_ORIENTATION);
+  } else if (aTypeAtom == nsGkAtoms::ondeviceproximity) {
+    EnableDevice(NS_DEVICE_PROXIMITY);
   } else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
     EnableDevice(NS_DEVICE_MOTION);
   } else if ((aType >= NS_MOZTOUCH_DOWN && aType <= NS_MOZTOUCH_UP) ||
              (aTypeAtom == nsGkAtoms::ontouchstart ||
               aTypeAtom == nsGkAtoms::ontouchend ||
               aTypeAtom == nsGkAtoms::ontouchmove ||
               aTypeAtom == nsGkAtoms::ontouchenter ||
               aTypeAtom == nsGkAtoms::ontouchleave ||
@@ -341,16 +343,19 @@ nsEventListenerManager::EnableDevice(PRU
   }
 
   NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
 
   switch (aType) {
     case NS_DEVICE_ORIENTATION:
       window->EnableDeviceSensor(SENSOR_ORIENTATION);
       break;
+    case NS_DEVICE_PROXIMITY:
+      window->EnableDeviceSensor(SENSOR_PROXIMITY);
+      break;
     case NS_DEVICE_MOTION:
       window->EnableDeviceSensor(SENSOR_ACCELERATION);
       window->EnableDeviceSensor(SENSOR_LINEAR_ACCELERATION);
       window->EnableDeviceSensor(SENSOR_GYROSCOPE);
       break;
     default:
       NS_WARNING("Enabling an unknown device sensor.");
       break;
@@ -371,16 +376,19 @@ nsEventListenerManager::DisableDevice(PR
     case NS_DEVICE_ORIENTATION:
       window->DisableDeviceSensor(SENSOR_ORIENTATION);
       break;
     case NS_DEVICE_MOTION:
       window->DisableDeviceSensor(SENSOR_ACCELERATION);
       window->DisableDeviceSensor(SENSOR_LINEAR_ACCELERATION);
       window->DisableDeviceSensor(SENSOR_GYROSCOPE);
       break;
+    case NS_DEVICE_PROXIMITY:
+      window->DisableDeviceSensor(SENSOR_PROXIMITY);
+      break;
     default:
       NS_WARNING("Disabling an unknown device sensor.");
       break;
   }
 }
 
 void
 nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, 
--- a/content/events/test/test_eventctors.html
+++ b/content/events/test/test_eventctors.html
@@ -364,16 +364,27 @@ ok(e.cancelable, "Event should be cancel
 is(e.key, "key", "Wrong value");
 is(e.oldValue, "oldValue", "Wrong value");
 is(e.newValue, "newValue", "Wrong value");
 is(e.url, "url", "Wrong value");
 is(e.storageArea, localStorage, "Wrong value");
 document.dispatchEvent(e);
 is(receivedEvent, e, "Wrong event!");
 
+// DeviceProximityEvent
+e = new DeviceProximityEvent("hello", {min: 0, value: 1, max: 2});
+ok(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.value, 1, "value should be 1");
+is(e.min, 0, "min should be 0");
+is(e.max, 2, "max should be 2");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+
 // MouseEvent
 
 try {
   e = new MouseEvent();
 } catch(exp) {
   ex = true;
 }
 ok(ex, "First parameter is required!");
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -320,16 +320,17 @@
 #include "nsIDOMCSSFontFaceRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsDOMCSSValueList.h"
+#include "nsIDOMDeviceProximityEvent.h"
 #include "nsIDOMDeviceOrientationEvent.h"
 #include "nsIDOMDeviceMotionEvent.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNodeIterator.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULCommandDispatcher.h"
@@ -808,16 +809,19 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(DragEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CompositionEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(PopupBlockedEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  // Device Proximity
+  NS_DEFINE_CLASSINFO_DATA(DeviceProximityEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   // Device Orientation
   NS_DEFINE_CLASSINFO_DATA(DeviceOrientationEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DeviceMotionEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DeviceAcceleration, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DeviceRotationRate, nsDOMGenericSH,
@@ -1687,16 +1691,18 @@ NS_DEFINE_EVENT_CTOR(Event)
 NS_DEFINE_EVENT_CTOR(CustomEvent)
 NS_DEFINE_EVENT_CTOR(PopStateEvent)
 NS_DEFINE_EVENT_CTOR(HashChangeEvent)
 NS_DEFINE_EVENT_CTOR(PageTransitionEvent)
 NS_DEFINE_EVENT_CTOR(CloseEvent)
 NS_DEFINE_EVENT_CTOR(MozSettingsEvent)
 NS_DEFINE_EVENT_CTOR(UIEvent)
 NS_DEFINE_EVENT_CTOR(MouseEvent)
+NS_DEFINE_EVENT_CTOR(DeviceProximityEvent)
+
 nsresult
 NS_DOMStorageEventCtor(nsISupports** aInstancePtrResult)
 {
   nsDOMStorageEvent* e = new nsDOMStorageEvent();
   return CallQueryInterface(e, aInstancePtrResult);
 }
 
 struct nsConstructorFuncMapData
@@ -1720,16 +1726,17 @@ static const nsConstructorFuncMapData kC
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(CustomEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(PopStateEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(HashChangeEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(PageTransitionEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(CloseEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozSettingsEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
+  NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(DeviceProximityEvent)
   NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(StorageEvent)
   NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozSmsFilter, sms::SmsFilter::NewSmsFilter)
 };
 
 nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
 nsIScriptSecurityManager *nsDOMClassInfo::sSecMan = nsnull;
 bool nsDOMClassInfo::sIsInitialized = false;
 bool nsDOMClassInfo::sDisableDocumentAllSupport = false;
@@ -2600,16 +2607,21 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(PopupBlockedEvent, nsIDOMPopupBlockedEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPopupBlockedEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(DeviceProximityEvent, nsIDOMDeviceProximityEvent)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceProximityEvent)
+    DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(DeviceOrientationEvent, nsIDOMDeviceOrientationEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceOrientationEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DeviceMotionEvent, nsIDOMDeviceMotionEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceMotionEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -74,16 +74,17 @@ DOMCI_CLASS(Event)
 DOMCI_CLASS(MutationEvent)
 DOMCI_CLASS(UIEvent)
 DOMCI_CLASS(MouseEvent)
 DOMCI_CLASS(MouseScrollEvent)
 DOMCI_CLASS(DragEvent)
 DOMCI_CLASS(KeyboardEvent)
 DOMCI_CLASS(CompositionEvent)
 DOMCI_CLASS(PopupBlockedEvent)
+DOMCI_CLASS(DeviceProximityEvent)
 DOMCI_CLASS(DeviceOrientationEvent)
 DOMCI_CLASS(DeviceMotionEvent)
 DOMCI_CLASS(DeviceAcceleration)
 DOMCI_CLASS(DeviceRotationRate)
 
 // HTML classes
 DOMCI_CLASS(HTMLDocument)
 DOMCI_CLASS(HTMLOptionsCollection)
--- a/dom/interfaces/base/nsIDOMWindow.idl
+++ b/dom/interfaces/base/nsIDOMWindow.idl
@@ -64,17 +64,17 @@ interface nsIDOMMozURLProperty : nsISupp
  * The nsIDOMWindow interface is the primary interface for a DOM
  * window object. It represents a single window object that may
  * contain child windows if the document in the window contains a
  * HTML frameset document or if the document contains iframe elements.
  *
  * @see <http://www.whatwg.org/html/#window>
  */
 
-[scriptable, uuid(f6e3b10d-d5f4-4fcd-aa4c-5f98626d428a)]
+[scriptable, uuid(627fa383-cb3c-498a-a5ed-ef2e9a827839)]
 interface nsIDOMWindow : nsISupports
 {
   // the current browsing context
   readonly attribute nsIDOMWindow                       window;
 
   /* [replaceable] self */
   readonly attribute nsIDOMWindow                       self;
 
@@ -459,16 +459,17 @@ interface nsIDOMWindow : nsISupports
   // [implicit_jscontext] attribute jsval onundo;
   [implicit_jscontext] attribute jsval onunload;
 
   /**
    * Non-HTML5 window-specific event attributes
    */
   [implicit_jscontext] attribute jsval ondevicemotion;
   [implicit_jscontext] attribute jsval ondeviceorientation;
+  [implicit_jscontext] attribute jsval ondeviceproximity;
 
   [implicit_jscontext] attribute jsval onmouseenter;
   [implicit_jscontext] attribute jsval onmouseleave;
 };
 
 [scriptable, uuid(2146c906-57f7-486c-a1b4-8cdb57ef577f)]
 interface nsIDOMWindowPerformance : nsISupports
 {
--- a/dom/interfaces/events/Makefile.in
+++ b/dom/interfaces/events/Makefile.in
@@ -70,17 +70,18 @@ XPIDLSRCS =					\
 	nsIDOMCommandEvent.idl			\
 	nsIDOMMessageEvent.idl			\
 	nsIDOMNotifyPaintEvent.idl              \
 	nsIDOMNotifyAudioAvailableEvent.idl     \
 	nsIDOMPaintRequest.idl			\
 	nsIDOMPaintRequestList.idl		\
 	nsIDOMSimpleGestureEvent.idl		\
 	nsIDOMMozTouchEvent.idl			\
-	nsIDOMDeviceOrientationEvent.idl\
+	nsIDOMDeviceProximityEvent.idl          \
+	nsIDOMDeviceOrientationEvent.idl        \
 	nsIDOMDeviceMotionEvent.idl		\
 	nsIDOMScrollAreaEvent.idl		\
 	nsIDOMTransitionEvent.idl		\
 	nsIDOMAnimationEvent.idl		\
 	nsIDOMPopStateEvent.idl			\
 	nsIDOMCloseEvent.idl			\
 	nsIDOMTouchEvent.idl			\
 	nsIDOMHashChangeEvent.idl		\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/events/nsIDOMDeviceProximityEvent.idl
@@ -0,0 +1,27 @@
+/* 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 "nsIDOMEvent.idl"
+
+[scriptable, uuid(4bb21c9b-381f-4c73-9000-5eb838f58738)]
+interface nsIDOMDeviceProximityEvent : nsIDOMEvent
+{
+  [noscript] void initDeviceProximityEvent(in DOMString eventTypeArg,
+                                           in boolean canBubbleArg,
+                                           in boolean cancelableArg,
+                                           in double value,
+                                           in double min,
+                                           in double max);
+  readonly attribute double value;
+  readonly attribute double min;
+  readonly attribute double max;
+};
+
+
+dictionary DeviceProximityEventInit : EventInit
+{
+   double value;
+   double min;
+   double max;
+};
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -215,21 +215,48 @@ nsDeviceSensors::Notify(const mozilla::h
     if (domdoc) {
       nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
       if (type == nsIDeviceSensorData::TYPE_ACCELERATION || 
         type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION || 
         type == nsIDeviceSensorData::TYPE_GYROSCOPE)
         FireDOMMotionEvent(domdoc, target, type, x, y, z);
       else if (type == nsIDeviceSensorData::TYPE_ORIENTATION)
         FireDOMOrientationEvent(domdoc, target, x, y, z);
+      else if (type == nsIDeviceSensorData::TYPE_PROXIMITY)
+        FireDOMProximityEvent(target, x, y, z);
     }
   }
 }
 
 void
+nsDeviceSensors::FireDOMProximityEvent(nsIDOMEventTarget *aTarget,
+                                       double aValue,
+                                       double aMin,
+                                       double aMax)
+{
+  nsCOMPtr<nsIDOMEvent> event;
+  NS_NewDOMDeviceProximityEvent(getter_AddRefs(event), nsnull, nsnull);
+  nsCOMPtr<nsIDOMDeviceProximityEvent> oe = do_QueryInterface(event);
+
+  oe->InitDeviceProximityEvent(NS_LITERAL_STRING("deviceproximity"),
+                               true,
+                               false,
+                               aValue,
+                               aMin,
+                               aMax);
+
+  nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
+  if (privateEvent) {
+    privateEvent->SetTrusted(true);
+  }
+  bool defaultActionEnabled;
+  aTarget->DispatchEvent(event, &defaultActionEnabled);
+}
+
+void
 nsDeviceSensors::FireDOMOrientationEvent(nsIDOMDocument *domdoc,
                                         nsIDOMEventTarget *target,
                                         double alpha,
                                         double beta,
                                         double gamma)
 {
   nsCOMPtr<nsIDOMEvent> event;
   bool defaultActionEnabled = true;
--- a/dom/system/nsDeviceSensors.h
+++ b/dom/system/nsDeviceSensors.h
@@ -39,16 +39,17 @@
 
 #include "nsIDeviceSensors.h"
 #include "nsIDOMDeviceMotionEvent.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
 #include "nsIDOMDeviceOrientationEvent.h"
+#include "nsIDOMDeviceProximityEvent.h"
 #include "nsIDOMDeviceMotionEvent.h"
 #include "nsDOMDeviceMotionEvent.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/HalSensor.h"
 #include "nsDataHashtable.h"
 
 #define NS_DEVICE_SENSORS_CID \
 { 0xecba5203, 0x77da, 0x465a, \
@@ -68,17 +69,22 @@ public:
 
   virtual ~nsDeviceSensors();
 
   void Notify(const mozilla::hal::SensorData& aSensorData);
 
 private:
   // sensor -> window listener
   nsTArray<nsTArray<nsIDOMWindow*>* > mWindowListeners;
-  
+
+  void FireDOMProximityEvent(nsIDOMEventTarget *aTarget,
+                             double aValue,
+                             double aMin,
+                             double aMax);
+
   void FireDOMOrientationEvent(class nsIDOMDocument *domDoc, 
                                class nsIDOMEventTarget *target,
                                double alpha,
                                double beta,
                                double gamma);
 
   void FireDOMMotionEvent(class nsIDOMDocument *domDoc, 
                           class nsIDOMEventTarget *target,
--- a/hal/gonk/GonkSensor.cpp
+++ b/hal/gonk/GonkSensor.cpp
@@ -104,16 +104,28 @@ public:
     }
     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 if (mSensorData.sensor() == SENSOR_PROXIMITY) {
+      mSensorValues.AppendElement(data.data[0]);
+      mSensorValues.AppendElement(0);     
+
+      // Determine the maxRange for this sensor.
+      const sensor_t* sensors = NULL;
+      size_t size = SensorDevice::getInstance().getSensorList(&sensors);
+      for (size_t i = 0; i < size; i++) {
+        if (sensors[i].type == SENSOR_TYPE_PROXIMITY) {
+          mSensorValues.AppendElement(sensors[i].maxRange);     
+        }
+      }
     } else {
       mSensorValues.AppendElement(data.data[0]);
       mSensorValues.AppendElement(data.data[1]);
       mSensorValues.AppendElement(data.data[2]);
     }
     mSensorData.values() = mSensorValues;
   }
 
--- a/js/xpconnect/src/dictionary_helper_gen.conf
+++ b/js/xpconnect/src/dictionary_helper_gen.conf
@@ -9,17 +9,18 @@ dictionaries = [
      [ 'UIEventInit', 'nsIDOMUIEvent.idl' ],
      [ 'MouseEventInit', 'nsIDOMMouseEvent.idl' ],
      [ 'IDBObjectStoreParameters', 'nsIIDBDatabase.idl' ],
      [ 'IDBIndexParameters', 'nsIIDBObjectStore.idl' ],
      [ 'StorageEventInit', 'nsIDOMStorageEvent.idl' ],
      [ 'BlobPropertyBag', 'nsIDOMFile.idl' ],
      [ 'MutationObserverInit', 'nsIDOMMutationObserver.idl' ],
      [ 'SettingsEventInit', 'nsIDOMSettingsManager.idl' ],
-     [ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl']
+     [ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl' ],
+     [ 'DeviceProximityEventInit', 'nsIDOMDeviceProximityEvent.idl' ]
    ]
 
 # include file names
 special_includes = [
     'nsContentUtils.h',
     'XPCQuickStubs.h'
   ]
 
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -685,17 +685,17 @@ public class GeckoAppShell
                 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);
+                sm.registerListener(GeckoApp.mAppContext, gProximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
             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 */);
             if (gLinearAccelerometerSensor != null)
                 sm.registerListener(GeckoApp.mAppContext, gLinearAccelerometerSensor, sDefaultSensorHint);
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -352,17 +352,20 @@ public class GeckoEvent {
             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.mMetaState = HalSensorAccuracyFor(s.accuracy);
             event.mX = s.values[0];
+            event.mY = 0;
+            event.mZ = s.sensor.getMaximumRange();
             break;
         }
         return event;
     }
 
     public static GeckoEvent createLocationEvent(Location l) {
         GeckoEvent event = new GeckoEvent(LOCATION_EVENT);
         event.mLocation = l;
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -537,16 +537,17 @@ class nsHashKey;
 #define NS_OPENCLOSE_EVENT_START     4800
 #define NS_OPEN                      (NS_OPENCLOSE_EVENT_START)
 #define NS_CLOSE                     (NS_OPENCLOSE_EVENT_START+1)
 
 // Device motion and orientation
 #define NS_DEVICE_ORIENTATION_START  4900
 #define NS_DEVICE_ORIENTATION        (NS_DEVICE_ORIENTATION_START)
 #define NS_DEVICE_MOTION             (NS_DEVICE_ORIENTATION_START+1)
+#define NS_DEVICE_PROXIMITY          (NS_DEVICE_ORIENTATION_START+2)
 
 #define NS_SHOW_EVENT                5000
 
 // Fullscreen DOM API
 #define NS_FULL_SCREEN_START         5100
 #define NS_FULLSCREENCHANGE          (NS_FULL_SCREEN_START)
 #define NS_FULLSCREENERROR           (NS_FULL_SCREEN_START + 1)