Bug 797798: System App can't Receive Sensor Event During Early Suspend State. r=jlebar
authorSteven Lee <slee@mozilla.com>
Wed, 24 Oct 2012 10:30:10 +0800
changeset 111344 b43af99c5e5b54fa0baff63af7dd5d73819e4d59
parent 111343 2583a19e59ef92cc1e5e5cdd9601c29504d9448c
child 111345 3593d9ccfec22d065ee4fa6065dca29be4990439
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersjlebar
bugs797798
milestone19.0a1
Bug 797798: System App can't Receive Sensor Event During Early Suspend State. r=jlebar
dom/apps/src/PermissionsInstaller.jsm
dom/system/nsDeviceSensors.cpp
--- a/dom/apps/src/PermissionsInstaller.jsm
+++ b/dom/apps/src/PermissionsInstaller.jsm
@@ -227,16 +227,21 @@ const PermissionsTable = { "resource-loc
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
                            },
                            "storage": {
                              app: DENY_ACTION,
                              privileged: DENY_ACTION,
                              certified: ALLOW_ACTION
                            },
+                           "background-sensors": {
+                             app: DENY_ACTION,
+                             privileged: DENY_ACTION,
+                             certified: ALLOW_ACTION
+                           },
                          };
 
 // Sometimes all permissions (fully expanded) need to be iterated through
 let AllPossiblePermissions = [];
 for (let permName in PermissionsTable) {
   if (PermissionsTable[permName].access) {
     AllPossiblePermissions =
       AllPossiblePermissions.concat(mapSuffixes(permName,
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -13,16 +13,17 @@
 #include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIServiceManager.h"
 #include "nsIServiceManager.h"
 #include "GeneratedEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Attributes.h"
+#include "nsIPermissionManager.h"
 
 using namespace mozilla;
 using namespace hal;
 
 #undef near
 
 // also see sDefaultSensorHint in mobile/android/base/GeckoAppShell.java
 #define DEFAULT_SENSOR_POLL 100
@@ -161,17 +162,39 @@ NS_IMETHODIMP nsDeviceSensors::RemoveWin
 NS_IMETHODIMP nsDeviceSensors::RemoveWindowAsListener(nsIDOMWindow *aWindow)
 {
   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     RemoveWindowListener((SensorType)i, aWindow);
   }
   return NS_OK;
 }
 
-void 
+static bool
+WindowCannotReceiveSensorEvent (nsPIDOMWindow* aWindow)
+{
+  // Check to see if this window is in the background.  If
+  // it is and it does not have the "background-sensors" permission,
+  // don't send any device motion events to it.
+  if (!aWindow || !aWindow->GetOuterWindow()) {
+    return true;
+  }
+
+  if (aWindow->GetOuterWindow()->IsBackground()) {
+    nsCOMPtr<nsIPermissionManager> permMgr =
+      do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+    NS_ENSURE_TRUE(permMgr, false);
+    uint32_t permission = nsIPermissionManager::DENY_ACTION;
+    permMgr->TestPermissionFromWindow(aWindow, "background-sensors", &permission);
+    return permission != nsIPermissionManager::ALLOW_ACTION;
+  }
+
+  return false;
+}
+
+void
 nsDeviceSensors::Notify(const mozilla::hal::SensorData& aSensorData)
 {
   uint32_t type = aSensorData.sensor();
 
   const InfallibleTArray<float>& values = aSensorData.values();
   size_t len = values.Length();
   double x = len > 0 ? values[0] : 0.0;
   double y = len > 1 ? values[1] : 0.0;
@@ -180,23 +203,20 @@ nsDeviceSensors::Notify(const mozilla::h
   nsCOMArray<nsIDOMWindow> windowListeners;
   for (uint32_t i = 0; i < mWindowListeners[type]->Length(); i++) {
     windowListeners.AppendObject(mWindowListeners[type]->SafeElementAt(i));
   }
 
   for (uint32_t i = windowListeners.Count(); i > 0 ; ) {
     --i;
 
-    // check to see if this window is in the background.  if
-    // it is, don't send any device motion to it.
     nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(windowListeners[i]);
-    if (!pwindow ||
-        !pwindow->GetOuterWindow() ||
-        pwindow->GetOuterWindow()->IsBackground())
-      continue;
+    if (WindowCannotReceiveSensorEvent(pwindow)) {
+        continue;
+    }
 
     nsCOMPtr<nsIDOMDocument> domdoc;
     windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
 
     if (domdoc) {
       nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
       if (type == nsIDeviceSensorData::TYPE_ACCELERATION || 
         type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION ||