tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsDeviceSensors.cpp (17847B)


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