Bug 1414698 - Part 2: Reset WEBVR_TIME_SPENT_VIEWING_IN_2D telemetry when the tab moves to the background; r=baku,kip
authorDaosheng Mu <daoshengmu@gmail.com>
Mon, 06 Nov 2017 18:04:07 +0800
changeset 443675 fb5d2596b7a0b5aa0d273c70f119ffc5c36a774d
parent 443674 46690f53a2f76e138d9d3518b31d641af1c39836
child 443678 44526b239ef05b1800548661812e98a0eba284b2
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, kip
bugs1414698
milestone58.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 1414698 - Part 2: Reset WEBVR_TIME_SPENT_VIEWING_IN_2D telemetry when the tab moves to the background; r=baku,kip MozReview-Commit-ID: 7TKKxNlpCNT
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/vr/VREventObserver.cpp
dom/vr/VREventObserver.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10636,23 +10636,31 @@ void nsGlobalWindow::SetIsBackground(boo
 
   if (inner && changed) {
     inner->mTimeoutManager->UpdateBackgroundState();
   }
 
   if (aIsBackground) {
     // Notify gamepadManager we are at the background window,
     // we need to stop vibrate.
+    // Stop the vr telemery time spent when it switches to
+    // the background window.
     if (inner && changed) {
       inner->StopGamepadHaptics();
+      // true is for asking to set the delta time to
+      // the telemetry.
+      inner->ResetVRTelemetry(true);
     }
     return;
   }
 
   if (inner) {
+    // When switching to be as a top tab, restart the telemetry.
+    // false is for only resetting the timestamp.
+    inner->ResetVRTelemetry(false);
     inner->SyncGamepadState();
   }
 }
 
 void
 nsGlobalWindow::SetIsBackgroundInternal(bool aIsBackground)
 {
   if (mIsBackground != aIsBackground) {
@@ -10719,16 +10727,24 @@ nsGlobalWindow::DisableVRUpdates()
   MOZ_ASSERT(IsInnerWindow());
   if (mVREventObserver) {
     mVREventObserver->DisconnectFromOwner();
     mVREventObserver = nullptr;
   }
 }
 
 void
+nsGlobalWindow::ResetVRTelemetry(bool aUpdate)
+{
+  if (mVREventObserver) {
+    mVREventObserver->UpdateSpentTimeIn2DTelemetry(aUpdate);
+  }
+}
+
+void
 nsGlobalWindow::SetChromeEventHandler(EventTarget* aChromeEventHandler)
 {
   MOZ_ASSERT(IsOuterWindow());
 
   SetChromeEventHandlerInternal(aChromeEventHandler);
   // update the chrome event handler on all our inner windows
   for (nsGlobalWindow *inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
        inner != this;
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -768,16 +768,20 @@ public:
   // Enable/disable updates for gamepad input.
   void EnableGamepadUpdates();
   void DisableGamepadUpdates();
 
   // Inner windows only.
   // Enable/disable updates for VR
   void EnableVRUpdates();
   void DisableVRUpdates();
+  // Reset telemetry data when switching windows.
+  // aUpdate, true for accumulating the result to the histogram.
+  // false for only resetting the timestamp.
+  void ResetVRTelemetry(bool aUpdate);
 
   // Update the VR displays for this window
   bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
 
   // Inner windows only.
   // Called to inform that the set of active VR displays has changed.
   void NotifyActiveVRDisplaysChanged();
 
--- a/dom/vr/VREventObserver.cpp
+++ b/dom/vr/VREventObserver.cpp
@@ -20,20 +20,21 @@ using namespace gfx;
 /**
  * This class is used by nsGlobalWindow to implement window.onvrdisplayactivate,
  * window.onvrdisplaydeactivate, window.onvrdisplayconnected,
  * window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange.
  */
 VREventObserver::VREventObserver(nsGlobalWindow* aGlobalWindow)
   : mWindow(aGlobalWindow)
   , mIs2DView(true)
+  , mHasReset(false)
 {
   MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow());
 
-  mSpendTimeIn2DView = TimeStamp::Now();
+  UpdateSpentTimeIn2DTelemetry(false);
   VRManagerChild* vmc = VRManagerChild::Get();
   if (vmc) {
     vmc->AddListener(this);
   }
 }
 
 VREventObserver::~VREventObserver()
 {
@@ -41,33 +42,47 @@ VREventObserver::~VREventObserver()
 }
 
 void
 VREventObserver::DisconnectFromOwner()
 {
   // In the event that nsGlobalWindow is deallocated, VREventObserver may
   // still be AddRef'ed elsewhere.  Ensure that we don't UAF by
   // dereferencing mWindow.
-  if (mWindow && mIs2DView) {
-    // The WebVR content is closed, and we will collect the telemetry info
-    // for the users who view it in 2D view only.
-    Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 0);
-    Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_2D,
-                                   mSpendTimeIn2DView);
-  }
+  UpdateSpentTimeIn2DTelemetry(true);
   mWindow = nullptr;
 
   // Unregister from VRManagerChild
   if (VRManagerChild::IsCreated()) {
     VRManagerChild* vmc = VRManagerChild::Get();
     vmc->RemoveListener(this);
   }
 }
 
 void
+VREventObserver::UpdateSpentTimeIn2DTelemetry(bool aUpdate)
+{
+  // mHasReset for avoiding setting the telemetry continuously
+  // for the telemetry is already been set when it is at the background.
+  // then, it would be set again when the process is exit and calling
+  // VREventObserver::DisconnectFromOwner().
+  if (mWindow && mIs2DView && aUpdate && mHasReset) {
+    // The WebVR content is closed, and we will collect the telemetry info
+    // for the users who view it in 2D view only.
+    Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 0);
+    Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_2D,
+                                   mSpendTimeIn2DView);
+    mHasReset = false;
+  } else if (!aUpdate) {
+    mSpendTimeIn2DView = TimeStamp::Now();
+    mHasReset = true;
+  }
+}
+
+void
 VREventObserver::NotifyVRDisplayMounted(uint32_t aDisplayID)
 {
   if (mWindow && mWindow->AsInner()->IsCurrentInnerWindow()) {
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayActivate(aDisplayID,
                                        VRDisplayEventReason::Mounted);
   }
 }
--- a/dom/vr/VREventObserver.h
+++ b/dom/vr/VREventObserver.h
@@ -25,23 +25,25 @@ public:
   void NotifyVRDisplayUnmounted(uint32_t aDisplayID);
   void NotifyVRDisplayNavigation(uint32_t aDisplayID);
   void NotifyVRDisplayRequested(uint32_t aDisplayID);
   void NotifyVRDisplayConnect(uint32_t aDisplayID);
   void NotifyVRDisplayDisconnect(uint32_t aDisplayID);
   void NotifyVRDisplayPresentChange(uint32_t aDisplayID);
 
   void DisconnectFromOwner();
+  void UpdateSpentTimeIn2DTelemetry(bool aUpdate);
 
 private:
   ~VREventObserver();
 
   RefPtr<nsGlobalWindow> mWindow;
   // For WebVR telemetry for tracking users who view content
   // in the 2D view.
   TimeStamp mSpendTimeIn2DView;
   bool mIs2DView;
+  bool mHasReset;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_VREventObserver_h