Bug 1306156 - Add telemetry for watching MAU and time spent of WebVR users; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Fri, 28 Jul 2017 18:42:11 +0800
changeset 617329 eac2df8a4a551951fe37d4d441be458f0cf466ac
parent 617159 556f19ef392ac2d9aac579864e2179d6c1d464e8
child 639801 cbeb5ec93ee51f3022f9576533b3041c7394cd5a
push id71036
push userbmo:dmu@mozilla.com
push dateFri, 28 Jul 2017 10:42:48 +0000
reviewerskip
bugs1306156
milestone56.0a1
Bug 1306156 - Add telemetry for watching MAU and time spent of WebVR users; r?kip MozReview-Commit-ID: 6v3F6aGdNK7
dom/vr/VREventObserver.cpp
dom/vr/VREventObserver.h
gfx/vr/gfxVROculus.cpp
gfx/vr/gfxVROculus.h
gfx/vr/gfxVROpenVR.cpp
gfx/vr/gfxVROpenVR.h
toolkit/components/telemetry/Histograms.json
--- a/dom/vr/VREventObserver.cpp
+++ b/dom/vr/VREventObserver.cpp
@@ -5,31 +5,35 @@
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "VREventObserver.h"
 
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "VRManagerChild.h"
 
+#include "mozilla/Telemetry.h"
+
 namespace mozilla {
 namespace dom {
 
 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)
 {
   MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow());
 
+  mSpendTimeIn2DView = TimeStamp::Now();
   VRManagerChild* vmc = VRManagerChild::Get();
   if (vmc) {
     vmc->AddListener(this);
   }
 }
 
 VREventObserver::~VREventObserver()
 {
@@ -37,16 +41,24 @@ 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::Accumulate(Telemetry::WEBVR_TIME_SPEND_FOR_VIEWING_IN_2D,
+                          static_cast<uint32_t>((TimeStamp::Now() - mSpendTimeIn2DView)
+                          .ToMilliseconds()));
+  }
   mWindow = nullptr;
 
   // Unregister from VRManagerChild
   if (VRManagerChild::IsCreated()) {
     VRManagerChild* vmc = VRManagerChild::Get();
     vmc->RemoveListener(this);
   }
 }
@@ -113,16 +125,20 @@ VREventObserver::NotifyVRDisplayDisconne
     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->AsInner()->IsCurrentInnerWindow()) {
     mWindow->NotifyActiveVRDisplaysChanged();
     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     mWindow->DispatchVRDisplayPresentChange(aDisplayID);
   }
 }
 
 } // namespace dom
--- a/dom/vr/VREventObserver.h
+++ b/dom/vr/VREventObserver.h
@@ -31,14 +31,18 @@ public:
 
   void DisconnectFromOwner();
 
 private:
   ~VREventObserver();
 
   // Weak pointer, instance is owned by mWindow.
   nsGlobalWindow* MOZ_NON_OWNING_REF mWindow;
+  // For WebVR telemetry for tracking users who view content
+  // in the 2D view.
+  TimeStamp mSpendTimeIn2DView;
+  bool mIs2DView;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_VREventObserver_h
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -26,16 +26,17 @@
 #include "CompositorD3D11.h"
 #include "TextureD3D11.h"
 
 #include "gfxVROculus.h"
 
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/dom/GamepadEventTypes.h"
 #include "mozilla/dom/GamepadBinding.h"
+#include "mozilla/Telemetry.h"
 
 /** XXX The DX11 objects and quad blitting could be encapsulated
  *    into a separate object if either Oculus starts supporting
  *     non-Windows platforms or the blit is needed by other HMD\
  *     drivers.
  *     Alternately, we could remove the extra blit for
  *     Oculus as well with some more refactoring.
  */
@@ -227,25 +228,30 @@ VROculusSession::StopTracking()
 
 void
 VROculusSession::StartPresentation(const IntSize& aSize)
 {
   if (!mPresenting) {
     mPresenting = true;
     mPresentationSize = aSize;
     Refresh();
+    mPresentationStart = TimeStamp::Now();
   }
 }
 
 void
 VROculusSession::StopPresentation()
 {
   if (mPresenting) {
     mLastPresentationEnd = TimeStamp::Now();
     mPresenting = false;
+    Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 1);
+    Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPEND_FOR_VIEWING_IN_OCULUS,
+                          static_cast<uint32_t>((TimeStamp::Now() - mPresentationStart)
+                          .ToMilliseconds()));
     Refresh();
   }
 }
 
 VROculusSession::~VROculusSession()
 {
   Uninitialize(true);
 }
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -58,16 +58,17 @@ private:
   nsTArray<RefPtr<layers::CompositingRenderTargetD3D11>> mRenderTargets;
   bool mPresenting;
   IntSize mPresentationSize;
   RefPtr<ID3D11Device> mDevice;
   // The timestamp of the last time Oculus set ShouldQuit to true.
   TimeStamp mLastShouldQuit;
   // The timestamp of the last ending presentation
   TimeStamp mLastPresentationEnd;
+  TimeStamp mPresentationStart;
 
   ~VROculusSession();
   void Uninitialize(bool aUnloadLib);
   bool Initialize(ovrInitFlags aFlags);
   bool LoadOvrLib();
   void UnloadOvrLib();
   bool StartSession();
   void StopSession();
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -24,16 +24,17 @@
 #include "VRManager.h"
 
 #include "nsServiceManagerUtils.h"
 #include "nsIScreenManager.h"
 
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/dom/GamepadEventTypes.h"
 #include "mozilla/dom/GamepadBinding.h"
+#include "mozilla/Telemetry.h"
 
 #ifndef M_PI
 # define M_PI 3.14159265358979323846
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::gfx::impl;
@@ -262,28 +263,33 @@ VRDisplayOpenVR::GetSensorState()
 
 void
 VRDisplayOpenVR::StartPresentation()
 {
   if (mIsPresenting) {
     return;
   }
   mIsPresenting = true;
+  mPresentationStart = TimeStamp::Now();
 }
 
 void
 VRDisplayOpenVR::StopPresentation()
 {
   if (!mIsPresenting) {
     return;
   }
 
   mVRCompositor->ClearLastSubmittedFrame();
 
   mIsPresenting = false;
+  Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 2);
+  Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPEND_FOR_VIEWING_IN_OPENVR,
+                        static_cast<uint32_t>((TimeStamp::Now() - mPresentationStart)
+                        .ToMilliseconds()));
 }
 
 bool
 VRDisplayOpenVR::SubmitFrame(void* aTextureHandle,
                              ::vr::ETextureType aTextureType,
                              const IntSize& aSize,
                              const gfx::Rect& aLeftEyeRect,
                              const gfx::Rect& aRightEyeRect)
@@ -315,17 +321,16 @@ VRDisplayOpenVR::SubmitFrame(void* aText
   bounds.vMax = 1.0 - aRightEyeRect.y - aRightEyeRect.height;
 
   err = mVRCompositor->Submit(::vr::EVREye::Eye_Right, &tex, &bounds);
   if (err != ::vr::EVRCompositorError::VRCompositorError_None) {
     printf_stderr("OpenVR Compositor Submit() failed.\n");
   }
 
   mVRCompositor->PostPresentHandoff();
-
   return true;
 }
 
 #if defined(XP_WIN)
 
 bool
 VRDisplayOpenVR::SubmitFrame(TextureSourceD3D11* aSource,
                              const IntSize& aSize,
--- a/gfx/vr/gfxVROpenVR.h
+++ b/gfx/vr/gfxVROpenVR.h
@@ -57,16 +57,17 @@ protected:
   virtual ~VRDisplayOpenVR();
   void Destroy();
 
   // not owned by us; global from OpenVR
   ::vr::IVRSystem *mVRSystem;
   ::vr::IVRChaperone *mVRChaperone;
   ::vr::IVRCompositor *mVRCompositor;
 
+  TimeStamp mPresentationStart;
   bool mIsPresenting;
 
   void UpdateStageParameters();
   void PollEvents();
   bool SubmitFrame(void* aTextureHandle,
                    ::vr::ETextureType aTextureType,
                    const IntSize& aSize,
                    const gfx::Rect& aLeftEyeRect,
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -13616,10 +13616,53 @@
     "alert_emails": ["alwu@mozilla.com"],
     "expires_in_version": "60",
     "kind": "exponential",
     "high": 10000,
     "n_buckets": 100,
     "bug_numbers": [1274919],
     "description": "Measure the time how long the cursor is hovering before opening the unselcted tab. Only record the data if someone requests for sending unselected tab hover msg.",
     "releaseChannelCollection": "opt-out"
+  },
+  "WEBVR_USERS_VIEW_IN": {
+    "record_in_processes": ["main", "gpu", "content"],
+    "alert_emails": ["dmu@mozilla.com"],
+    "bug_numbers": [1306156],
+    "expires_in_version": "never",
+    "kind": "enumerated",
+    "n_values": 3,
+    "releaseChannelCollection": "opt-out",
+    "description": "The amount of users who view VR content in: 2D=0, Oculus=1, OpenVR=2."
+  },
+  "WEBVR_TIME_SPEND_FOR_VIEWING_IN_2D": {
+    "record_in_processes": ["main", "content"],
+    "alert_emails": ["dmu@mozilla.com"],
+    "bug_numbers": [1306156],
+    "expires_in_version": "never",
+    "kind": "exponential",
+    "high": 50000,
+    "n_buckets": 100,
+    "releaseChannelCollection": "opt-out",
+    "description": "The amount of time spend(ms) for users who view VR content in 2D."
+  },
+  "WEBVR_TIME_SPEND_FOR_VIEWING_IN_OCULUS": {
+    "record_in_processes": ["main", "gpu"],
+    "alert_emails": ["dmu@mozilla.com"],
+    "bug_numbers": [1306156],
+    "expires_in_version": "never",
+    "kind": "exponential",
+    "high": 50000,
+    "n_buckets": 100,
+    "releaseChannelCollection": "opt-out",
+    "description": "The amount of time spend(ms) for users who view VR content in Oculus."
+  },
+  "WEBVR_TIME_SPEND_FOR_VIEWING_IN_OPENVR": {
+    "record_in_processes": ["main", "gpu"],
+    "alert_emails": ["dmu@mozilla.com"],
+    "bug_numbers": [1306156],
+    "expires_in_version": "never",
+    "kind": "exponential",
+    "high": 50000,
+    "n_buckets": 100,
+    "releaseChannelCollection": "opt-out",
+    "description": "The amount of time spend(ms) for users who view VR content in OpenVR."
   }
 }