Bug 1345077 - Part 1 - Add an isHandlingUserInput flag to WebRTC permission requests. r=baku,padenot draft
authorJohann Hofmann <jhofmann@mozilla.com>
Wed, 10 Jan 2018 23:59:55 +0100
changeset 723589 3e3bec9b81fa436bfedf8b50b8ed0c0bec61b59c
parent 722069 abbe0ca5d9693e06484fcb52bbcac189c3461f50
child 723590 b7d8063191a020b785a5f5e4aa46fac135e4dd11
push id96477
push userjhofmann@mozilla.com
push dateTue, 23 Jan 2018 15:45:45 +0000
reviewersbaku, padenot
bugs1345077
milestone59.0a1
Bug 1345077 - Part 1 - Add an isHandlingUserInput flag to WebRTC permission requests. r=baku,padenot MozReview-Commit-ID: SGu9lWjPH5
dom/media/GetUserMediaRequest.cpp
dom/media/GetUserMediaRequest.h
dom/media/MediaManager.cpp
dom/webidl/GetUserMediaRequest.webidl
--- a/dom/media/GetUserMediaRequest.cpp
+++ b/dom/media/GetUserMediaRequest.cpp
@@ -11,22 +11,24 @@
 
 namespace mozilla {
 namespace dom {
 
 GetUserMediaRequest::GetUserMediaRequest(
     nsPIDOMWindowInner* aInnerWindow,
     const nsAString& aCallID,
     const MediaStreamConstraints& aConstraints,
-    bool aIsSecure)
+    bool aIsSecure,
+    bool aIsHandlingUserInput)
   : mInnerWindowID(aInnerWindow->WindowID())
   , mOuterWindowID(aInnerWindow->GetOuterWindow()->WindowID())
   , mCallID(aCallID)
   , mConstraints(new MediaStreamConstraints(aConstraints))
   , mIsSecure(aIsSecure)
+  , mIsHandlingUserInput(aIsHandlingUserInput)
 {
 }
 
 GetUserMediaRequest::GetUserMediaRequest(
     nsPIDOMWindowInner* aInnerWindow,
     const nsAString& aRawId,
     const nsAString& aMediaSource)
   : mRawID(aRawId)
@@ -81,16 +83,21 @@ uint64_t GetUserMediaRequest::InnerWindo
   return mInnerWindowID;
 }
 
 bool GetUserMediaRequest::IsSecure()
 {
   return mIsSecure;
 }
 
+bool GetUserMediaRequest::IsHandlingUserInput() const
+{
+  return mIsHandlingUserInput;
+}
+
 void
 GetUserMediaRequest::GetConstraints(MediaStreamConstraints &result)
 {
   result = *mConstraints;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/GetUserMediaRequest.h
+++ b/dom/media/GetUserMediaRequest.h
@@ -18,42 +18,45 @@ namespace dom {
 struct MediaStreamConstraints;
 
 class GetUserMediaRequest : public nsISupports, public nsWrapperCache
 {
 public:
   GetUserMediaRequest(nsPIDOMWindowInner* aInnerWindow,
                       const nsAString& aCallID,
                       const MediaStreamConstraints& aConstraints,
-                      bool aIsSecure);
+                      bool aIsSecure,
+                      bool aIsHandlingUserInput);
   GetUserMediaRequest(nsPIDOMWindowInner* aInnerWindow,
                       const nsAString& aRawId,
                       const nsAString& aMediaSource);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GetUserMediaRequest)
 
   JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
   nsISupports* GetParentObject();
 
   uint64_t WindowID();
   uint64_t InnerWindowID();
   bool IsSecure();
+  bool IsHandlingUserInput() const;
   void GetCallID(nsString& retval);
   void GetRawID(nsString& retval);
   void GetMediaSource(nsString& retval);
   void GetConstraints(MediaStreamConstraints &result);
 
 private:
   virtual ~GetUserMediaRequest() {}
 
   uint64_t mInnerWindowID, mOuterWindowID;
   const nsString mCallID;
   const nsString mRawID;
   const nsString mMediaSource;
   nsAutoPtr<MediaStreamConstraints> mConstraints;
   bool mIsSecure;
+  bool mIsHandlingUserInput;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // GetUserMediaRequest_h__
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -25,16 +25,17 @@
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsICryptoHash.h"
 #include "nsICryptoHMAC.h"
 #include "nsIKeyModule.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIInputStream.h"
 #include "nsILineInputStream.h"
+#include "mozilla/EventStateManager.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Types.h"
 #include "mozilla/PeerIdentity.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/MediaStreamBinding.h"
@@ -2229,16 +2230,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
   nsIURI* docURI = aWindow->GetDocumentURI();
   if (!docURI) {
     return NS_ERROR_UNEXPECTED;
   }
   bool isChrome = (aCallerType == dom::CallerType::System);
   bool privileged = isChrome ||
       Preferences::GetBool("media.navigator.permission.disabled", false);
   bool isHTTPS = false;
+  bool isHandlingUserInput = EventStateManager::IsHandlingUserInput();;
   docURI->SchemeIs("https", &isHTTPS);
   nsCString host;
   nsresult rv = docURI->GetHost(host);
   // Test for some other schemes that ServiceWorker recognizes
   bool isFile;
   docURI->SchemeIs("file", &isFile);
   bool isApp;
   docURI->SchemeIs("app", &isApp);
@@ -2521,32 +2523,33 @@ MediaManager::GetUserMedia(nsPIDOMWindow
   bool askPermission =
       (!privileged || Preferences::GetBool("media.navigator.permission.force")) &&
       (realDevicesRequested || Preferences::GetBool("media.navigator.permission.fake"));
 
   RefPtr<PledgeSourceSet> p = EnumerateDevicesImpl(windowID, videoType,
                                                    audioType, fake);
   RefPtr<MediaManager> self = this;
   p->Then([self, onSuccess, onFailure, windowID, c, windowListener,
-           sourceListener, askPermission, prefs, isHTTPS, callID, principalInfo,
-           isChrome, resistFingerprinting](SourceSet*& aDevices) mutable {
+           sourceListener, askPermission, prefs, isHTTPS, isHandlingUserInput,
+           callID, principalInfo, isChrome, resistFingerprinting](SourceSet*& aDevices) mutable {
     // grab result
     auto devices = MakeRefPtr<Refcountable<UniquePtr<SourceSet>>>(aDevices);
 
     // Ensure that our windowID is still good.
     if (!nsGlobalWindowInner::GetInnerWindowWithId(windowID)) {
       return;
     }
 
     // Apply any constraints. This modifies the passed-in list.
     RefPtr<PledgeChar> p2 = self->SelectSettings(c, isChrome, devices);
 
     p2->Then([self, onSuccess, onFailure, windowID, c,
               windowListener, sourceListener, askPermission, prefs, isHTTPS,
-              callID, principalInfo, isChrome, devices, resistFingerprinting
+              isHandlingUserInput, callID, principalInfo, isChrome, devices,
+              resistFingerprinting
              ](const char*& badConstraint) mutable {
 
       // Ensure that the captured 'this' pointer and our windowID are still good.
       auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(windowID);
       RefPtr<nsPIDOMWindowInner> window = globalWindow ? globalWindow->AsInner()
                                                        : nullptr;
       if (!MediaManager::Exists() || !window) {
         return;
@@ -2609,17 +2612,17 @@ MediaManager::GetUserMedia(nsPIDOMWindow
       array->AppendElement(callID);
 
       nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
       if (!askPermission) {
         obs->NotifyObservers(devicesCopy, "getUserMedia:privileged:allow",
                              callID.BeginReading());
       } else {
         RefPtr<GetUserMediaRequest> req =
-            new GetUserMediaRequest(window, callID, c, isHTTPS);
+            new GetUserMediaRequest(window, callID, c, isHTTPS, isHandlingUserInput);
         if (!Preferences::GetBool("media.navigator.permission.force") && array->Length() > 1) {
           // there is at least 1 pending gUM request
           // For the scarySources test case, always send the request
           self->mPendingGUMRequest.AppendElement(req.forget());
         } else {
           obs->NotifyObservers(req, "getUserMedia:request", nullptr);
         }
       }
--- a/dom/webidl/GetUserMediaRequest.webidl
+++ b/dom/webidl/GetUserMediaRequest.webidl
@@ -17,9 +17,10 @@
 interface GetUserMediaRequest {
   readonly attribute unsigned long long windowID;
   readonly attribute unsigned long long innerWindowID;
   readonly attribute DOMString callID;
   readonly attribute DOMString rawID;
   readonly attribute DOMString mediaSource;
   MediaStreamConstraints getConstraints();
   readonly attribute boolean isSecure;
+  readonly attribute boolean isHandlingUserInput;
 };