LCOV - code coverage report
Current view: top level - dom/system - nsDeviceSensors.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 291 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 34 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/Hal.h"
       8             : #include "mozilla/HalSensor.h"
       9             : 
      10             : #include "nsContentUtils.h"
      11             : #include "nsDeviceSensors.h"
      12             : 
      13             : #include "nsIDOMEvent.h"
      14             : #include "nsIDOMWindow.h"
      15             : #include "nsPIDOMWindow.h"
      16             : #include "nsIDOMDocument.h"
      17             : #include "nsIScriptObjectPrincipal.h"
      18             : #include "nsIServiceManager.h"
      19             : #include "nsIServiceManager.h"
      20             : #include "mozilla/Preferences.h"
      21             : #include "mozilla/Attributes.h"
      22             : #include "mozilla/Services.h"
      23             : #include "nsIPermissionManager.h"
      24             : #include "mozilla/dom/DeviceLightEvent.h"
      25             : #include "mozilla/dom/DeviceOrientationEvent.h"
      26             : #include "mozilla/dom/DeviceProximityEvent.h"
      27             : #include "mozilla/dom/UserProximityEvent.h"
      28             : 
      29             : #include <cmath>
      30             : 
      31             : using namespace mozilla;
      32             : using namespace mozilla::dom;
      33             : using namespace hal;
      34             : 
      35             : #undef near
      36             : 
      37             : #define DEFAULT_SENSOR_POLL 100
      38             : 
      39             : static const nsTArray<nsIDOMWindow*>::index_type NoIndex =
      40             :   nsTArray<nsIDOMWindow*>::NoIndex;
      41             : 
      42             : class nsDeviceSensorData final : public nsIDeviceSensorData
      43             : {
      44             : public:
      45             :   NS_DECL_ISUPPORTS
      46             :   NS_DECL_NSIDEVICESENSORDATA
      47             : 
      48             :   nsDeviceSensorData(unsigned long type, double x, double y, double z);
      49             : 
      50             : private:
      51             :   ~nsDeviceSensorData();
      52             : 
      53             : protected:
      54             :   unsigned long mType;
      55             :   double mX, mY, mZ;
      56             : };
      57             : 
      58           0 : nsDeviceSensorData::nsDeviceSensorData(unsigned long type, double x, double y, double z)
      59           0 :   : mType(type), mX(x), mY(y), mZ(z)
      60             : {
      61           0 : }
      62             : 
      63           0 : NS_INTERFACE_MAP_BEGIN(nsDeviceSensorData)
      64           0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDeviceSensorData)
      65           0 : NS_INTERFACE_MAP_END
      66             : 
      67           0 : NS_IMPL_ADDREF(nsDeviceSensorData)
      68           0 : NS_IMPL_RELEASE(nsDeviceSensorData)
      69             : 
      70           0 : nsDeviceSensorData::~nsDeviceSensorData()
      71             : {
      72           0 : }
      73             : 
      74           0 : NS_IMETHODIMP nsDeviceSensorData::GetType(uint32_t *aType)
      75             : {
      76           0 :   NS_ENSURE_ARG_POINTER(aType);
      77           0 :   *aType = mType;
      78           0 :   return NS_OK;
      79             : }
      80             : 
      81           0 : NS_IMETHODIMP nsDeviceSensorData::GetX(double *aX)
      82             : {
      83           0 :   NS_ENSURE_ARG_POINTER(aX);
      84           0 :   *aX = mX;
      85           0 :   return NS_OK;
      86             : }
      87             : 
      88           0 : NS_IMETHODIMP nsDeviceSensorData::GetY(double *aY)
      89             : {
      90           0 :   NS_ENSURE_ARG_POINTER(aY);
      91           0 :   *aY = mY;
      92           0 :   return NS_OK;
      93             : }
      94             : 
      95           0 : NS_IMETHODIMP nsDeviceSensorData::GetZ(double *aZ)
      96             : {
      97           0 :   NS_ENSURE_ARG_POINTER(aZ);
      98           0 :   *aZ = mZ;
      99           0 :   return NS_OK;
     100             : }
     101             : 
     102           0 : NS_IMPL_ISUPPORTS(nsDeviceSensors, nsIDeviceSensors)
     103             : 
     104           0 : nsDeviceSensors::nsDeviceSensors()
     105             : {
     106           0 :   mIsUserProximityNear = false;
     107           0 :   mLastDOMMotionEventTime = TimeStamp::Now();
     108           0 :   mEnabled = Preferences::GetBool("device.sensors.enabled", true);
     109             : 
     110           0 :   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     111           0 :     nsTArray<nsIDOMWindow*> *windows = new nsTArray<nsIDOMWindow*>();
     112           0 :     mWindowListeners.AppendElement(windows);
     113             :   }
     114             : 
     115           0 :   mLastDOMMotionEventTime = TimeStamp::Now();
     116           0 : }
     117             : 
     118           0 : nsDeviceSensors::~nsDeviceSensors()
     119             : {
     120           0 :   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     121           0 :     if (IsSensorEnabled(i))
     122           0 :       UnregisterSensorObserver((SensorType)i, this);
     123             :   }
     124             : 
     125           0 :   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     126           0 :     delete mWindowListeners[i];
     127             :   }
     128           0 : }
     129             : 
     130           0 : NS_IMETHODIMP nsDeviceSensors::HasWindowListener(uint32_t aType, nsIDOMWindow *aWindow, bool *aRetVal)
     131             : {
     132           0 :   if (AreSensorEventsDisabled(aWindow))
     133           0 :     *aRetVal = false;
     134             :   else
     135           0 :     *aRetVal = mWindowListeners[aType]->IndexOf(aWindow) != NoIndex;
     136             : 
     137           0 :   return NS_OK;
     138             : }
     139             : 
     140           0 : class DeviceSensorTestEvent : public Runnable
     141             : {
     142             : public:
     143           0 :   DeviceSensorTestEvent(nsDeviceSensors* aTarget, uint32_t aType)
     144           0 :     : mozilla::Runnable("DeviceSensorTestEvent")
     145             :     , mTarget(aTarget)
     146           0 :     , mType(aType)
     147             :   {
     148           0 :   }
     149             : 
     150           0 :   NS_IMETHOD Run() override
     151             :   {
     152           0 :     SensorData sensorData;
     153           0 :     sensorData.sensor() = static_cast<SensorType>(mType);
     154           0 :     sensorData.timestamp() = PR_Now();
     155           0 :     sensorData.values().AppendElement(0.5f);
     156           0 :     sensorData.values().AppendElement(0.5f);
     157           0 :     sensorData.values().AppendElement(0.5f);
     158           0 :     sensorData.values().AppendElement(0.5f);
     159           0 :     sensorData.accuracy() = SENSOR_ACCURACY_UNRELIABLE;
     160           0 :     mTarget->Notify(sensorData);
     161           0 :     return NS_OK;
     162             :   }
     163             : 
     164             : private:
     165             :   RefPtr<nsDeviceSensors> mTarget;
     166             :   uint32_t mType;
     167             : };
     168             : 
     169             : static bool sTestSensorEvents = false;
     170             : 
     171           0 : NS_IMETHODIMP nsDeviceSensors::AddWindowListener(uint32_t aType, nsIDOMWindow *aWindow)
     172             : {
     173           0 :   if (AreSensorEventsDisabled(aWindow))
     174           0 :     return NS_OK;
     175             : 
     176           0 :   if (mWindowListeners[aType]->IndexOf(aWindow) != NoIndex)
     177           0 :     return NS_OK;
     178             : 
     179           0 :   if (!IsSensorEnabled(aType)) {
     180           0 :     RegisterSensorObserver((SensorType)aType, this);
     181             :   }
     182             : 
     183           0 :   mWindowListeners[aType]->AppendElement(aWindow);
     184             : 
     185             :   static bool sPrefCacheInitialized = false;
     186           0 :   if (!sPrefCacheInitialized) {
     187           0 :     sPrefCacheInitialized = true;
     188             :     Preferences::AddBoolVarCache(&sTestSensorEvents,
     189             :                                  "device.sensors.test.events",
     190           0 :                                  false);
     191             :   }
     192             : 
     193           0 :   if (sTestSensorEvents) {
     194           0 :     nsCOMPtr<nsIRunnable> event = new DeviceSensorTestEvent(this, aType);
     195           0 :     NS_DispatchToCurrentThread(event);
     196             :   }
     197             : 
     198           0 :   return NS_OK;
     199             : }
     200             : 
     201           0 : NS_IMETHODIMP nsDeviceSensors::RemoveWindowListener(uint32_t aType, nsIDOMWindow *aWindow)
     202             : {
     203           0 :   if (mWindowListeners[aType]->IndexOf(aWindow) == NoIndex)
     204           0 :     return NS_OK;
     205             : 
     206           0 :   mWindowListeners[aType]->RemoveElement(aWindow);
     207             : 
     208           0 :   if (mWindowListeners[aType]->Length() == 0)
     209           0 :     UnregisterSensorObserver((SensorType)aType, this);
     210             : 
     211           0 :   return NS_OK;
     212             : }
     213             : 
     214           0 : NS_IMETHODIMP nsDeviceSensors::RemoveWindowAsListener(nsIDOMWindow *aWindow)
     215             : {
     216           0 :   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     217           0 :     RemoveWindowListener((SensorType)i, aWindow);
     218             :   }
     219           0 :   return NS_OK;
     220             : }
     221             : 
     222             : static bool
     223           0 : WindowCannotReceiveSensorEvent (nsPIDOMWindowInner* aWindow)
     224             : {
     225             :   // Check to see if this window is in the background.  If
     226             :   // it is and it does not have the "background-sensors" permission,
     227             :   // don't send any device motion events to it.
     228           0 :   if (!aWindow || !aWindow->IsCurrentInnerWindow()) {
     229           0 :     return true;
     230             :   }
     231             : 
     232           0 :   bool disabled = aWindow->GetOuterWindow()->IsBackground() ||
     233           0 :                   !aWindow->IsTopLevelWindowActive();
     234           0 :   if (!disabled) {
     235           0 :     nsCOMPtr<nsPIDOMWindowOuter> top = aWindow->GetScriptableTop();
     236           0 :     nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
     237           0 :     nsCOMPtr<nsIScriptObjectPrincipal> topSop = do_QueryInterface(top);
     238           0 :     if (!sop || !topSop) {
     239           0 :       return true;
     240             :     }
     241             : 
     242           0 :     nsIPrincipal* principal = sop->GetPrincipal();
     243           0 :     nsIPrincipal* topPrincipal = topSop->GetPrincipal();
     244           0 :     if (!principal || !topPrincipal) {
     245           0 :       return true;
     246             :     }
     247             : 
     248           0 :     disabled = !principal->Subsumes(topPrincipal);
     249             :   }
     250             : 
     251           0 :   if (disabled) {
     252             :     nsCOMPtr<nsIPermissionManager> permMgr =
     253           0 :       services::GetPermissionManager();
     254           0 :     NS_ENSURE_TRUE(permMgr, true);
     255           0 :     uint32_t permission = nsIPermissionManager::DENY_ACTION;
     256           0 :     permMgr->TestPermissionFromWindow(aWindow, "background-sensors", &permission);
     257           0 :     return permission != nsIPermissionManager::ALLOW_ACTION;
     258             :   }
     259             : 
     260           0 :   return false;
     261             : }
     262             : 
     263             : // Holds the device orientation in Euler angle degrees (azimuth, pitch, roll).
     264             : struct Orientation
     265             : {
     266             :   enum OrientationReference
     267             :   {
     268             :     kRelative = 0,
     269             :     kAbsolute
     270             :   };
     271             : 
     272           0 :   static Orientation RadToDeg(const Orientation& aOrient)
     273             :   {
     274             :     const static double kRadToDeg = 180.0 / M_PI;
     275           0 :     return { aOrient.alpha * kRadToDeg,
     276           0 :              aOrient.beta * kRadToDeg,
     277           0 :              aOrient.gamma * kRadToDeg };
     278             :   }
     279             : 
     280             :   double alpha;
     281             :   double beta;
     282             :   double gamma;
     283             : };
     284             : 
     285             : static Orientation
     286           0 : RotationVectorToOrientation(double aX, double aY, double aZ, double aW)
     287             : {
     288             :   static const double kFuzzyOne = 1.0 - 1e-6;
     289             :   static const double kCircleRad = 2.0 * M_PI;
     290             : 
     291           0 :   Orientation orient = { 2.0 * std::atan2(aY, aW),
     292             :                          M_PI_2,
     293           0 :                          0.0 };
     294             : 
     295           0 :   const double sqX = aX * aX;
     296           0 :   const double sqY = aY * aY;
     297           0 :   const double sqZ = aZ * aZ;
     298           0 :   const double sqW = aW * aW;
     299           0 :   const double unitLength = sqX + sqY + sqZ + sqW;
     300           0 :   const double xwyz = 2.0 * (aX * aW + aY * aZ) / unitLength;
     301             : 
     302           0 :   if (xwyz < -kFuzzyOne) {
     303           0 :     orient.alpha *= -1.0;
     304           0 :     orient.beta *= -1.0;
     305           0 :   } else if (xwyz <= kFuzzyOne) {
     306           0 :     const double gammaX = -sqX - sqY + sqZ + sqW;
     307           0 :     const double gammaY = 2.0 * (aY * aW - aX * aZ);
     308           0 :     const double alphaX = -sqX + sqY - sqZ + sqW;
     309           0 :     const double alphaY = 2.0 * (aZ * aW - aX * aY);
     310           0 :     const double fac = gammaX > 0 ? 1.0 : -1.0;
     311             : 
     312           0 :     orient.alpha = std::fmod(kCircleRad + std::atan2(fac * alphaY, fac * alphaX),
     313             :                              kCircleRad);
     314           0 :     orient.beta = fac * std::asin(xwyz);
     315           0 :     orient.gamma = std::atan2(fac * gammaY, fac * gammaX);
     316           0 :     if (fac < 0.0) {
     317           0 :       orient.beta = fmod(M_PI + orient.beta, M_PI);
     318             :     }
     319             :   }
     320             : 
     321           0 :   return Orientation::RadToDeg(orient);
     322             : }
     323             : 
     324             : void
     325           0 : nsDeviceSensors::Notify(const mozilla::hal::SensorData& aSensorData)
     326             : {
     327           0 :   uint32_t type = aSensorData.sensor();
     328             : 
     329           0 :   const InfallibleTArray<float>& values = aSensorData.values();
     330           0 :   size_t len = values.Length();
     331           0 :   double x = len > 0 ? values[0] : 0.0;
     332           0 :   double y = len > 1 ? values[1] : 0.0;
     333           0 :   double z = len > 2 ? values[2] : 0.0;
     334           0 :   double w = len > 3 ? values[3] : 0.0;
     335           0 :   PRTime timestamp = aSensorData.timestamp();
     336             : 
     337           0 :   nsCOMArray<nsIDOMWindow> windowListeners;
     338           0 :   for (uint32_t i = 0; i < mWindowListeners[type]->Length(); i++) {
     339           0 :     windowListeners.AppendObject(mWindowListeners[type]->SafeElementAt(i));
     340             :   }
     341             : 
     342           0 :   for (uint32_t i = windowListeners.Count(); i > 0 ; ) {
     343           0 :     --i;
     344             : 
     345           0 :     nsCOMPtr<nsPIDOMWindowInner> pwindow = do_QueryInterface(windowListeners[i]);
     346           0 :     if (WindowCannotReceiveSensorEvent(pwindow)) {
     347           0 :         continue;
     348             :     }
     349             : 
     350           0 :     if (nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(pwindow->GetDoc())) {
     351           0 :       nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(windowListeners[i]);
     352           0 :       if (type == nsIDeviceSensorData::TYPE_ACCELERATION ||
     353           0 :         type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION ||
     354             :         type == nsIDeviceSensorData::TYPE_GYROSCOPE) {
     355           0 :         FireDOMMotionEvent(domDoc, target, type, timestamp, x, y, z);
     356           0 :       } else if (type == nsIDeviceSensorData::TYPE_ORIENTATION) {
     357           0 :         FireDOMOrientationEvent(target, x, y, z, Orientation::kAbsolute);
     358           0 :       } else if (type == nsIDeviceSensorData::TYPE_ROTATION_VECTOR) {
     359           0 :         const Orientation orient = RotationVectorToOrientation(x, y, z, w);
     360           0 :         FireDOMOrientationEvent(target, orient.alpha, orient.beta, orient.gamma,
     361           0 :                                 Orientation::kAbsolute);
     362           0 :       } else if (type == nsIDeviceSensorData::TYPE_GAME_ROTATION_VECTOR) {
     363           0 :         const Orientation orient = RotationVectorToOrientation(x, y, z, w);
     364           0 :         FireDOMOrientationEvent(target, orient.alpha, orient.beta, orient.gamma,
     365           0 :                                 Orientation::kRelative);
     366           0 :       } else if (type == nsIDeviceSensorData::TYPE_PROXIMITY) {
     367           0 :         FireDOMProximityEvent(target, x, y, z);
     368           0 :       } else if (type == nsIDeviceSensorData::TYPE_LIGHT) {
     369           0 :         FireDOMLightEvent(target, x);
     370             :       }
     371             :     }
     372             :   }
     373           0 : }
     374             : 
     375             : void
     376           0 : nsDeviceSensors::FireDOMLightEvent(mozilla::dom::EventTarget* aTarget,
     377             :                                    double aValue)
     378             : {
     379           0 :   DeviceLightEventInit init;
     380           0 :   init.mBubbles = true;
     381           0 :   init.mCancelable = false;
     382           0 :   init.mValue = round(aValue);
     383             :   RefPtr<DeviceLightEvent> event =
     384           0 :     DeviceLightEvent::Constructor(aTarget, NS_LITERAL_STRING("devicelight"), init);
     385             : 
     386           0 :   event->SetTrusted(true);
     387             : 
     388             :   bool defaultActionEnabled;
     389           0 :   aTarget->DispatchEvent(event, &defaultActionEnabled);
     390           0 : }
     391             : 
     392             : void
     393           0 : nsDeviceSensors::FireDOMProximityEvent(mozilla::dom::EventTarget* aTarget,
     394             :                                        double aValue,
     395             :                                        double aMin,
     396             :                                        double aMax)
     397             : {
     398           0 :   DeviceProximityEventInit init;
     399           0 :   init.mBubbles = true;
     400           0 :   init.mCancelable = false;
     401           0 :   init.mValue = aValue;
     402           0 :   init.mMin = aMin;
     403           0 :   init.mMax = aMax;
     404             :   RefPtr<DeviceProximityEvent> event =
     405           0 :     DeviceProximityEvent::Constructor(aTarget,
     406           0 :                                       NS_LITERAL_STRING("deviceproximity"),
     407           0 :                                       init);
     408           0 :   event->SetTrusted(true);
     409             : 
     410             :   bool defaultActionEnabled;
     411           0 :   aTarget->DispatchEvent(event, &defaultActionEnabled);
     412             : 
     413             :   // Some proximity sensors only support a binary near or
     414             :   // far measurement. In this case, the sensor should report
     415             :   // its maximum range value in the far state and a lesser
     416             :   // value in the near state.
     417             : 
     418           0 :   bool near = (aValue < aMax);
     419           0 :   if (mIsUserProximityNear != near) {
     420           0 :     mIsUserProximityNear = near;
     421           0 :     FireDOMUserProximityEvent(aTarget, mIsUserProximityNear);
     422             :   }
     423           0 : }
     424             : 
     425             : void
     426           0 : nsDeviceSensors::FireDOMUserProximityEvent(mozilla::dom::EventTarget* aTarget,
     427             :                                            bool aNear)
     428             : {
     429           0 :   UserProximityEventInit init;
     430           0 :   init.mBubbles = true;
     431           0 :   init.mCancelable = false;
     432           0 :   init.mNear = aNear;
     433             :   RefPtr<UserProximityEvent> event =
     434           0 :     UserProximityEvent::Constructor(aTarget,
     435           0 :                                     NS_LITERAL_STRING("userproximity"),
     436           0 :                                     init);
     437             : 
     438           0 :   event->SetTrusted(true);
     439             : 
     440             :   bool defaultActionEnabled;
     441           0 :   aTarget->DispatchEvent(event, &defaultActionEnabled);
     442           0 : }
     443             : 
     444             : void
     445           0 : nsDeviceSensors::FireDOMOrientationEvent(EventTarget* aTarget,
     446             :                                          double aAlpha,
     447             :                                          double aBeta,
     448             :                                          double aGamma,
     449             :                                          bool aIsAbsolute)
     450             : {
     451           0 :   DeviceOrientationEventInit init;
     452           0 :   init.mBubbles = true;
     453           0 :   init.mCancelable = false;
     454           0 :   init.mAlpha.SetValue(aAlpha);
     455           0 :   init.mBeta.SetValue(aBeta);
     456           0 :   init.mGamma.SetValue(aGamma);
     457           0 :   init.mAbsolute = aIsAbsolute;
     458             : 
     459           0 :   auto Dispatch = [&](EventTarget* aEventTarget, const nsAString& aType)
     460             :   {
     461             :     RefPtr<DeviceOrientationEvent> event =
     462           0 :       DeviceOrientationEvent::Constructor(aEventTarget, aType, init);
     463           0 :     event->SetTrusted(true);
     464             :     bool dummy;
     465           0 :     aEventTarget->DispatchEvent(event, &dummy);
     466           0 :   };
     467             : 
     468           0 :   Dispatch(aTarget, aIsAbsolute ? NS_LITERAL_STRING("absolutedeviceorientation") :
     469           0 :                                   NS_LITERAL_STRING("deviceorientation"));
     470             : 
     471             :   // This is used to determine whether relative events have been dispatched
     472             :   // during the current session, in which case we don't dispatch the additional
     473             :   // compatibility events.
     474             :   static bool sIsDispatchingRelativeEvents = false;
     475           0 :   sIsDispatchingRelativeEvents = sIsDispatchingRelativeEvents || !aIsAbsolute;
     476             : 
     477             :   // Android devices with SENSOR_GAME_ROTATION_VECTOR support dispatch
     478             :   // relative events for "deviceorientation" by default, while other platforms
     479             :   // and devices without such support dispatch absolute events by default.
     480           0 :   if (aIsAbsolute && !sIsDispatchingRelativeEvents) {
     481             :     // For absolute events on devices without support for relative events,
     482             :     // we need to additionally dispatch type "deviceorientation" to keep
     483             :     // backwards-compatibility.
     484           0 :     Dispatch(aTarget, NS_LITERAL_STRING("deviceorientation"));
     485             :   }
     486           0 : }
     487             : 
     488             : void
     489           0 : nsDeviceSensors::FireDOMMotionEvent(nsIDOMDocument *domdoc,
     490             :                                     EventTarget* target,
     491             :                                     uint32_t type,
     492             :                                     PRTime timestamp,
     493             :                                     double x,
     494             :                                     double y,
     495             :                                     double z)
     496             : {
     497             :   // Attempt to coalesce events
     498             :   TimeDuration sensorPollDuration =
     499           0 :     TimeDuration::FromMilliseconds(DEFAULT_SENSOR_POLL);
     500             :   bool fireEvent =
     501           0 :     (TimeStamp::Now() > mLastDOMMotionEventTime + sensorPollDuration) ||
     502           0 :     sTestSensorEvents;
     503             : 
     504           0 :   switch (type) {
     505             :   case nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION:
     506           0 :     if (!mLastAcceleration) {
     507           0 :       mLastAcceleration.emplace();
     508             :     }
     509           0 :     mLastAcceleration->mX.SetValue(x);
     510           0 :     mLastAcceleration->mY.SetValue(y);
     511           0 :     mLastAcceleration->mZ.SetValue(z);
     512           0 :     break;
     513             :   case nsIDeviceSensorData::TYPE_ACCELERATION:
     514           0 :     if (!mLastAccelerationIncludingGravity) {
     515           0 :       mLastAccelerationIncludingGravity.emplace();
     516             :     }
     517           0 :     mLastAccelerationIncludingGravity->mX.SetValue(x);
     518           0 :     mLastAccelerationIncludingGravity->mY.SetValue(y);
     519           0 :     mLastAccelerationIncludingGravity->mZ.SetValue(z);
     520           0 :     break;
     521             :   case nsIDeviceSensorData::TYPE_GYROSCOPE:
     522           0 :     if (!mLastRotationRate) {
     523           0 :       mLastRotationRate.emplace();
     524             :     }
     525           0 :     mLastRotationRate->mAlpha.SetValue(x);
     526           0 :     mLastRotationRate->mBeta.SetValue(y);
     527           0 :     mLastRotationRate->mGamma.SetValue(z);
     528           0 :     break;
     529             :   }
     530             : 
     531           0 :   if (fireEvent) {
     532           0 :     if (!mLastAcceleration) {
     533           0 :       mLastAcceleration.emplace();
     534             :     }
     535           0 :     if (!mLastAccelerationIncludingGravity) {
     536           0 :       mLastAccelerationIncludingGravity.emplace();
     537             :     }
     538           0 :     if (!mLastRotationRate) {
     539           0 :       mLastRotationRate.emplace();
     540             :     }
     541           0 :   } else if (!mLastAcceleration ||
     542           0 :              !mLastAccelerationIncludingGravity ||
     543           0 :              !mLastRotationRate) {
     544           0 :     return;
     545             :   }
     546             : 
     547           0 :   nsCOMPtr<nsIDOMEvent> event;
     548           0 :   domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event));
     549             : 
     550           0 :   DeviceMotionEvent* me = static_cast<DeviceMotionEvent*>(event.get());
     551             : 
     552           0 :   me->InitDeviceMotionEvent(NS_LITERAL_STRING("devicemotion"),
     553             :                             true,
     554             :                             false,
     555           0 :                             *mLastAcceleration,
     556           0 :                             *mLastAccelerationIncludingGravity,
     557           0 :                             *mLastRotationRate,
     558           0 :                             Nullable<double>(DEFAULT_SENSOR_POLL),
     559           0 :                             Nullable<uint64_t>(timestamp));
     560             : 
     561           0 :   event->SetTrusted(true);
     562             : 
     563           0 :   bool defaultActionEnabled = true;
     564           0 :   target->DispatchEvent(event, &defaultActionEnabled);
     565             : 
     566           0 :   mLastRotationRate.reset();
     567           0 :   mLastAccelerationIncludingGravity.reset();
     568           0 :   mLastAcceleration.reset();
     569           0 :   mLastDOMMotionEventTime = TimeStamp::Now();
     570             : }
     571             : 
     572             : bool
     573           0 : nsDeviceSensors::AreSensorEventsDisabled(nsIDOMWindow* aWindow)
     574             : {
     575           0 :   if (!mEnabled) {
     576           0 :     return true;
     577             :   }
     578             : 
     579           0 :   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aWindow);
     580             : 
     581           0 :   if (!window) {
     582           0 :     return false;
     583             :   }
     584             : 
     585           0 :   return nsContentUtils::ShouldResistFingerprinting(window->GetDocShell());
     586             : }

Generated by: LCOV version 1.13