Bug 1627331 - Do not dispatch WebVR events when the display is used via WebXR API r=kip,daoshengmu
authorImanol Fernandez <mortimergoro@gmail.com>
Tue, 07 Apr 2020 20:37:00 +0000
changeset 523441 5c7fdf2a3d71a9d0a6627f82181dd315162c226a
parent 523440 8408be2ed5fc44fcd404e6713ec7168f0d3907c5
child 523442 bab62d72587a0924397d8423ac445968b4f48e86
push id37302
push usercbrindusan@mozilla.com
push dateSat, 11 Apr 2020 09:34:41 +0000
treeherdermozilla-central@06ee15775ba8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip, daoshengmu
bugs1627331
milestone77.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
Bug 1627331 - Do not dispatch WebVR events when the display is used via WebXR API r=kip,daoshengmu Differential Revision: https://phabricator.services.mozilla.com/D69613
dom/vr/VREventObserver.cpp
dom/vr/VREventObserver.h
gfx/vr/VRDisplayClient.cpp
gfx/vr/VRDisplayClient.h
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerChild.h
--- a/dom/vr/VREventObserver.cpp
+++ b/dom/vr/VREventObserver.cpp
@@ -87,89 +87,97 @@ bool VREventObserver::GetStopActivitySta
 void VREventObserver::NotifyAfterLoad() {
   if (VRManagerChild::IsCreated()) {
     VRManagerChild* vmc = VRManagerChild::Get();
     vmc->FireDOMVRDisplayConnectEventsForLoad(this);
   }
 }
 
 void VREventObserver::NotifyVRDisplayMounted(uint32_t aDisplayID) {
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayActivate(aDisplayID,
                                        VRDisplayEventReason::Mounted);
   }
 }
 
 void VREventObserver::NotifyVRDisplayNavigation(uint32_t aDisplayID) {
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayActivate(aDisplayID,
                                        VRDisplayEventReason::Navigation);
   }
 }
 
 void VREventObserver::NotifyVRDisplayRequested(uint32_t aDisplayID) {
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayActivate(aDisplayID,
                                        VRDisplayEventReason::Requested);
   }
 }
 
 void VREventObserver::NotifyVRDisplayUnmounted(uint32_t aDisplayID) {
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayDeactivate(aDisplayID,
                                          VRDisplayEventReason::Unmounted);
   }
 }
 
 void VREventObserver::NotifyVRDisplayConnect(uint32_t aDisplayID) {
   /**
    * We do not call nsGlobalWindow::NotifyActiveVRDisplaysChanged here, as we
    * can assume that a newly enumerated display is not presenting WebVR
    * content.
    */
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayConnect(aDisplayID);
   }
 }
 
 void VREventObserver::NotifyVRDisplayDisconnect(uint32_t aDisplayID) {
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     mWindow->NotifyActiveVRDisplaysChanged();
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayDisconnect(aDisplayID);
   }
 }
 
 void VREventObserver::NotifyVRDisplayPresentChange(uint32_t aDisplayID) {
   // When switching to HMD present mode, it is no longer
   // to be a 2D view.
   mIs2DView = false;
 
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     mWindow->NotifyActiveVRDisplaysChanged();
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayPresentChange(aDisplayID);
   }
 }
 
 void VREventObserver::NotifyPresentationGenerationChanged(uint32_t aDisplayID) {
-  if (mWindow && mWindow->IsCurrentInnerWindow()) {
+  if (mWindow && mWindow->IsCurrentInnerWindow() && IsWebVR(aDisplayID)) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->NotifyPresentationGenerationChanged(aDisplayID);
   }
 }
 
 void VREventObserver::NotifyEnumerationCompleted() {}
 
 void VREventObserver::NotifyDetectRuntimesCompleted() {
   if (mWindow && mWindow->IsCurrentInnerWindow()) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->NotifyDetectXRRuntimesCompleted();
   }
 }
 
+bool VREventObserver::IsWebVR(uint32_t aDisplayID) const {
+  VRManagerChild* vmc = VRManagerChild::Get();
+  if (vmc) {
+    return vmc->GetVRAPIMode(aDisplayID) == gfx::VRAPIMode::WebVR;
+  }
+  return true;
+}
+
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/vr/VREventObserver.h
+++ b/dom/vr/VREventObserver.h
@@ -37,16 +37,18 @@ class VREventObserver final : public gfx
   void UpdateSpentTimeIn2DTelemetry(bool aUpdate);
   void StartActivity();
   void StopActivity();
   bool GetStopActivityStatus() const override;
 
  private:
   ~VREventObserver();
 
+  bool IsWebVR(uint32_t aDisplayID) const;
+
   RefPtr<nsGlobalWindowInner> mWindow;
   // For WebVR telemetry for tracking users who view content
   // in the 2D view.
   TimeStamp mSpendTimeIn2DView;
   bool mIs2DView;
   bool mHasReset;
   bool mStopActivity;
 };
--- a/gfx/vr/VRDisplayClient.cpp
+++ b/gfx/vr/VRDisplayClient.cpp
@@ -98,16 +98,20 @@ bool VRDisplayClient::IsPresentationGene
 
   return true;
 }
 
 void VRDisplayClient::MakePresentationGenerationCurrent() {
   mLastPresentingGeneration = mDisplayInfo.mDisplayState.presentingGeneration;
 }
 
+gfx::VRAPIMode VRDisplayClient::GetXRAPIMode() const {
+  return mAPIMode;
+}
+
 void VRDisplayClient::SetXRAPIMode(gfx::VRAPIMode aMode) {
   mAPIMode = aMode;
 }
 
 void VRDisplayClient::FireEvents() {
   RefPtr<VRManagerChild> vm = VRManagerChild::Get();
   // Only fire these events for non-chrome VR sessions
   bool isPresenting = (mDisplayInfo.mPresentingGroups & kVRGroupContent) != 0;
--- a/gfx/vr/VRDisplayClient.h
+++ b/gfx/vr/VRDisplayClient.h
@@ -52,16 +52,17 @@ class VRDisplayClient {
   bool IsPresentationGenerationCurrent() const;
   void MakePresentationGenerationCurrent();
 
   void StartVRNavigation();
   void StopVRNavigation(const TimeDuration& aTimeout);
 
   bool IsPresenting();
   bool IsReferenceSpaceTypeSupported(dom::XRReferenceSpaceType aType) const;
+  gfx::VRAPIMode GetXRAPIMode() const;
   void SetXRAPIMode(gfx::VRAPIMode aMode);
 
  protected:
   virtual ~VRDisplayClient();
 
   MOZ_CAN_RUN_SCRIPT void FireEvents();
   void FireGamepadEvents();
   MOZ_CAN_RUN_SCRIPT void StartFrame();
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -581,16 +581,25 @@ void VRManagerChild::HandleFatalError(co
   dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherPid());
 }
 
 void VRManagerChild::AddPromise(const uint32_t& aID, dom::Promise* aPromise) {
   MOZ_ASSERT(!mGamepadPromiseList.Get(aID, nullptr));
   mGamepadPromiseList.Put(aID, RefPtr{aPromise});
 }
 
+gfx::VRAPIMode VRManagerChild::GetVRAPIMode(uint32_t aDisplayID) const {
+  for (auto& display : mDisplays) {
+    if (display->GetDisplayInfo().GetDisplayID() == aDisplayID) {
+      return display->GetXRAPIMode();
+    }
+  }
+  return VRAPIMode::WebXR;
+}
+
 mozilla::ipc::IPCResult VRManagerChild::RecvReplyGamepadVibrateHaptic(
     const uint32_t& aPromiseID) {
   // VRManagerChild could be at other processes, but GamepadManager
   // only exists at the content process or the same process
   // in non-e10s mode.
   MOZ_ASSERT(XRE_IsContentProcess() || IsSameProcess());
 
   RefPtr<dom::Promise> p;
--- a/gfx/vr/ipc/VRManagerChild.h
+++ b/gfx/vr/ipc/VRManagerChild.h
@@ -68,16 +68,17 @@ class VRManagerChild : public PVRManager
   bool RuntimeSupportsAR() const;
   bool RuntimeSupportsInline() const;
 
   void GetVRDisplays(nsTArray<RefPtr<VRDisplayClient>>& aDisplays);
   bool RefreshVRDisplaysWithCallback(uint64_t aWindowId);
   bool EnumerateVRDisplays();
   void DetectRuntimes();
   void AddPromise(const uint32_t& aID, dom::Promise* aPromise);
+  gfx::VRAPIMode GetVRAPIMode(uint32_t aDisplayID) const;
 
   static void InitSameProcess();
   static void InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint);
   static bool InitForContent(Endpoint<PVRManagerChild>&& aEndpoint);
   static void ShutDown();
 
   static bool IsCreated();
   static bool IsPresenting();