Bug 1528078 - Adding WebRTC device access and deprecated interface telemetry r=jib,smaug
authorNico Grunbaum <na-g@nostrum.com>
Fri, 03 May 2019 23:50:22 +0000
changeset 531435 25bc2e11f12fa6b52e8783dd468f72cfeda3f025
parent 531434 ce409badd9d99ebef2b56471d88631a9da5400c1
child 531436 e86a75908fd3f530563496cee8777f0e64e3fd20
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib, smaug
bugs1528078
milestone68.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 1528078 - Adding WebRTC device access and deprecated interface telemetry r=jib,smaug Adding telemetry for gUM, enumerate devices, and mozRTCPeerConnection Differential Revision: https://phabricator.services.mozilla.com/D23103
dom/base/Navigator.cpp
dom/base/UseCounters.conf
dom/media/MediaDevices.cpp
dom/media/MediaDevices.h
dom/webidl/MediaDevices.webidl
dom/webidl/Navigator.webidl
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1272,17 +1272,30 @@ void Navigator::MozGetUserMediaDevices(
     MozGetUserMediaDevicesSuccessCallback& aOnSuccess,
     NavigatorUserMediaErrorCallback& aOnError, uint64_t aInnerWindowID,
     const nsAString& aCallID, ErrorResult& aRv) {
   if (!mWindow || !mWindow->GetOuterWindow() ||
       mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
-
+  if (Document* doc = mWindow->GetExtantDoc()) {
+    if (!mWindow->IsSecureContext()) {
+      doc->SetDocumentAndPageUseCounter(
+          eUseCounter_custom_MozGetUserMediaInsec);
+    }
+    nsINode* node = doc;
+    while ((node = nsContentUtils::GetCrossDocParentNode(node))) {
+      if (NS_FAILED(nsContentUtils::CheckSameOrigin(doc, node))) {
+        doc->SetDocumentAndPageUseCounter(
+            eUseCounter_custom_MozGetUserMediaXOrigin);
+        break;
+      }
+    }
+  }
   RefPtr<MediaManager> manager = MediaManager::Get();
   // XXXbz aOnError seems to be unused?
   nsCOMPtr<nsPIDOMWindowInner> window(mWindow);
   aRv = manager->GetUserMediaDevices(window, aConstraints, aOnSuccess,
                                      aInnerWindowID, aCallID);
 }
 
 //*****************************************************************************
--- a/dom/base/UseCounters.conf
+++ b/dom/base/UseCounters.conf
@@ -126,8 +126,23 @@ custom DocumentOpen calls document.open 
 
 custom FilteredCrossOriginIFrame cross-origin <iframe> within a CSS/SVG filter
 
 // Custom Elements
 method CustomElementRegistry.define
 
 // Shadow DOM
 method Element.attachShadow
+
+// Media Device Access
+method MediaDevices.enumerateDevices
+custom EnumerateDevicesInsec calls MediaDevices.enumerateDevices from an insecure context
+custom EnumerateDevicesUnfocused calls MediaDevices.enumerateDevices from a unfocused document
+method MediaDevices.getUserMedia
+method Navigator.mozGetUserMedia
+custom GetUserMediaUnfocused calls MediaDevices.getUserMedia from an unfocused document
+custom GetUserMediaInsec calls MediaDevices.getUserMedia from an insecure context
+custom MozGetUserMediaInsec calls Navigator.mozGetUserMedia from an insecure context
+custom GetUserMediaXOrigin calls MediaDevices.getUserMedia from a cross origin context
+custom MozGetUserMediaXOrigin calls Navigator.mozGetUserMedia from a cross origin context
+method MediaDevices.getDisplayMedia
+custom GetDisplayMediaXOrigin calls MediaDevices.getDisplayMedia from a cross origin context
+
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -50,19 +50,44 @@ NS_IMPL_ISUPPORTS(FuzzTimerCallBack, nsI
 
 MediaDevices::~MediaDevices() {
   MediaManager* mediamanager = MediaManager::GetIfExists();
   if (mediamanager) {
     mediamanager->RemoveDeviceChangeCallback(this);
   }
 }
 
+static bool IsSameOriginWithAllParentDocs(nsINode* aDoc) {
+  MOZ_ASSERT(aDoc);
+  nsINode* node = aDoc;
+  while ((node = nsContentUtils::GetCrossDocParentNode(node))) {
+    if (NS_FAILED(nsContentUtils::CheckSameOrigin(aDoc, node))) {
+      return false;
+    }
+  }
+  return true;
+}
+
 already_AddRefed<Promise> MediaDevices::GetUserMedia(
     const MediaStreamConstraints& aConstraints, CallerType aCallerType,
     ErrorResult& aRv) {
+  if (Document* doc = GetOwner()->GetExtantDoc()) {
+    if (!GetOwner()->IsSecureContext()) {
+      doc->SetDocumentAndPageUseCounter(eUseCounter_custom_GetUserMediaInsec);
+    }
+    if (!IsSameOriginWithAllParentDocs(doc)) {
+      doc->SetDocumentAndPageUseCounter(eUseCounter_custom_GetUserMediaXOrigin);
+    }
+    Document* topDoc = doc->GetTopLevelContentDocument();
+    IgnoredErrorResult ignored;
+    if (topDoc && !topDoc->HasFocus(ignored)) {
+      doc->SetDocumentAndPageUseCounter(
+          eUseCounter_custom_GetUserMediaUnfocused);
+    }
+  }
   RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
   RefPtr<MediaDevices> self(this);
   MediaManager::Get()
       ->GetUserMedia(GetOwner(), aConstraints, aCallerType)
       ->Then(
@@ -81,16 +106,29 @@ already_AddRefed<Promise> MediaDevices::
             p->MaybeReject(MakeRefPtr<MediaStreamError>(window, *error));
           });
   return p.forget();
 }
 
 already_AddRefed<Promise> MediaDevices::EnumerateDevices(CallerType aCallerType,
                                                          ErrorResult& aRv) {
   MOZ_ASSERT(NS_IsMainThread());
+
+  if (Document* doc = GetOwner()->GetExtantDoc()) {
+    if (!GetOwner()->IsSecureContext()) {
+      doc->SetDocumentAndPageUseCounter(
+          eUseCounter_custom_EnumerateDevicesInsec);
+    }
+    Document* topDoc = doc->GetTopLevelContentDocument();
+    IgnoredErrorResult ignored;
+    if (topDoc && !topDoc->HasFocus(ignored)) {
+      doc->SetDocumentAndPageUseCounter(
+          eUseCounter_custom_EnumerateDevicesUnfocused);
+    }
+  }
   RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
   RefPtr<MediaDevices> self(this);
   MediaManager::Get()
       ->EnumerateDevices(GetOwner(), aCallerType)
       ->Then(
@@ -129,16 +167,22 @@ already_AddRefed<Promise> MediaDevices::
             p->MaybeReject(MakeRefPtr<MediaStreamError>(window, *error));
           });
   return p.forget();
 }
 
 already_AddRefed<Promise> MediaDevices::GetDisplayMedia(
     const DisplayMediaStreamConstraints& aConstraints, CallerType aCallerType,
     ErrorResult& aRv) {
+  if (Document* doc = GetOwner()->GetExtantDoc()) {
+    if (!IsSameOriginWithAllParentDocs(doc)) {
+      doc->SetDocumentAndPageUseCounter(
+          eUseCounter_custom_GetDisplayMediaXOrigin);
+    }
+  }
   RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
   RefPtr<MediaDevices> self(this);
   MediaManager::Get()
       ->GetDisplayMedia(GetOwner(), aConstraints, aCallerType)
       ->Then(
--- a/dom/media/MediaDevices.h
+++ b/dom/media/MediaDevices.h
@@ -64,16 +64,18 @@ class MediaDevices final : public DOMEve
 
  private:
   class GumResolver;
   class EnumDevResolver;
   class GumRejecter;
 
   virtual ~MediaDevices();
   nsCOMPtr<nsITimer> mFuzzTimer;
+
+  void RecordAccessTelemetry(const UseCounter counter) const;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(MediaDevices,
                               MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/webidl/MediaDevices.webidl
+++ b/dom/webidl/MediaDevices.webidl
@@ -11,17 +11,17 @@
  */
 
 [Func="Navigator::HasUserMediaSupport"]
 interface MediaDevices : EventTarget {
   [Pref="media.ondevicechange.enabled"]
   attribute EventHandler ondevicechange;
   MediaTrackSupportedConstraints getSupportedConstraints();
 
-  [Throws, NeedsCallerType]
+  [Throws, NeedsCallerType, UseCounter]
   Promise<sequence<MediaDeviceInfo>> enumerateDevices();
 
-  [Throws, NeedsCallerType]
+  [Throws, NeedsCallerType, UseCounter]
   Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
 
-  [SecureContext, Throws, NeedsCallerType]
+  [SecureContext, Throws, NeedsCallerType, UseCounter]
   Promise<MediaStream> getDisplayMedia(optional DisplayMediaStreamConstraints constraints);
 };
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -239,17 +239,18 @@ callback NavigatorUserMediaErrorCallback
 
 partial interface Navigator {
   [Throws, Func="Navigator::HasUserMediaSupport"]
   readonly attribute MediaDevices mediaDevices;
 
   // Deprecated. Use mediaDevices.getUserMedia instead.
   [Deprecated="NavigatorGetUserMedia", Throws,
    Func="Navigator::HasUserMediaSupport",
-   NeedsCallerType]
+   NeedsCallerType,
+   UseCounter]
   void mozGetUserMedia(MediaStreamConstraints constraints,
                        NavigatorUserMediaSuccessCallback successCallback,
                        NavigatorUserMediaErrorCallback errorCallback);
 };
 
 // nsINavigatorUserMedia
 callback MozGetUserMediaDevicesSuccessCallback = void (nsIVariant? devices);
 partial interface Navigator {